From 2b6538ccc1fb8c88da17beafbc0f9f4651f721f2 Mon Sep 17 00:00:00 2001 From: nrp Date: Sun, 31 Aug 2008 00:09:49 +0000 Subject: Merge branch 'master' of git://dev.laptop.org/projects/physics03 Conflicts: physics.py tools.py --- diff --git a/bridge.py b/bridge.py index bebd9e1..7f63c8a 100644 --- a/bridge.py +++ b/bridge.py @@ -1,47 +1,75 @@ import pygame -def create_world(game): - rect = pygame.Rect((0,800), (350, -250)) - rect.normalize() - pygame.draw.rect(game.screen, (100,180,255), rect, 3) - game.world.add.rect(rect.center, rect.width / 2, rect.height / 2, - dynamic=False) - rect = pygame.Rect((1200,800), (-350, -250)) - rect.normalize() - pygame.draw.rect(game.screen, (100,180,255), rect, 3) - game.world.add.rect(rect.center, rect.width / 2, rect.height / 2, - dynamic=False) +class Bridge: + def __init__(self, game): + self.game = game + self.screen = game.screen + self.world = game.world + self.joints = [] + self.cost = 0 -def create_train(game, worldpoint = (300,500), train = (100, 50), wheelrad = 20, cars = 3): - points = [] - for i in range(0,cars): - startpoint = (worldpoint[0]-(train[0]+7)*i, worldpoint[1]) - points.append(startpoint) - rect = pygame.Rect(startpoint, train) + def create_world(self): + rect = pygame.Rect((0,800), (350, -250)) rect.normalize() - pygame.draw.rect(game.screen, (200, 50, 100), rect, 3) + pygame.draw.rect(self.screen, (100,180,255), rect, 3) + self.world.add.rect(rect.center, rect.width / 2, rect.height / 2, + dynamic=False) + rect = pygame.Rect((1200,800), (-350, -250)) + rect.normalize() + pygame.draw.rect(self.screen, (100,180,255), rect, 3) + self.world.add.rect(rect.center, rect.width / 2, rect.height / 2, + dynamic=False) + + def add_cost(self, value): + self.cost = self.cost + value + print "cost now", value - game.world.add.rect(rect.center, rect.width / 2, rect.height / 2, - dynamic = True, density=1.0, restitution=0.16, friction=0.5) + def joint_added(self, joint): + print "joint added!" + self.joints.append(joint) + self.add_cost(100) - rearwheel = (startpoint[0]+wheelrad,startpoint[1]+train[1]-wheelrad/2) - pygame.draw.circle(game.screen, (0,0,0), rearwheel, wheelrad, 3) - game.world.add.ball(rearwheel,wheelrad, dynamic=True, density=1.0, - restitution=0.16, friction=0.5) + def box_added(self): + self.add_cost(10) - frontwheel = (startpoint[0]+train[0]-wheelrad,startpoint[1]+train[1]-wheelrad/2) - pygame.draw.circle(game.screen, (0,0,0), frontwheel, wheelrad, 3) - game.world.add.ball(frontwheel,wheelrad, dynamic=True, density=1.0, - restitution=0.16, friction=0.5) + def for_each_frame(self): + for joint in self.joints: + force = joint.GetReactionForce().Length() + if force > 500: + print "destroy joint!" + self.world.world.DestroyJoint(joint) + self.joints.remove(joint) - rearaxle = game.world.get_bodies_at_pos(rearwheel) - frontaxle = game.world.get_bodies_at_pos(frontwheel) - game.world.add.jointMotor(rearaxle[0],rearaxle[1],rearwheel) - game.world.add.jointMotor(frontaxle[0],frontaxle[1],frontwheel) - - for i in range(1,len(points)): - backlink = (points[i][0]+train[0]-1,points[i][1]+train[1]-1) - frontlink = (points[i-1][0]+1,points[i-1][1]+train[1]-1) - btrain = game.world.get_bodies_at_pos(backlink) - ftrain = game.world.get_bodies_at_pos(frontlink) - game.world.add.distanceJoint(btrain[0], ftrain[0], backlink, frontlink) + def create_train(game, worldpoint = (300,500), train = (100, 50), wheelrad = 20, cars = 3): + points = [] + for i in range(0,cars): + startpoint = (worldpoint[0]-(train[0]+7)*i, worldpoint[1]) + points.append(startpoint) + rect = pygame.Rect(startpoint, train) + rect.normalize() + pygame.draw.rect(game.screen, (200, 50, 100), rect, 3) + + game.world.add.rect(rect.center, rect.width / 2, rect.height / 2, + dynamic = True, density=1.0, restitution=0.16, friction=0.5) + + rearwheel = (startpoint[0]+wheelrad,startpoint[1]+train[1]-wheelrad/2) + pygame.draw.circle(game.screen, (0,0,0), rearwheel, wheelrad, 3) + game.world.add.ball(rearwheel,wheelrad, dynamic=True, density=1.0, + restitution=0.16, friction=0.5) + + frontwheel = (startpoint[0]+train[0]-wheelrad,startpoint[1]+train[1]-wheelrad/2) + pygame.draw.circle(game.screen, (0,0,0), frontwheel, wheelrad, 3) + game.world.add.ball(frontwheel,wheelrad, dynamic=True, density=1.0, + restitution=0.16, friction=0.5) + + rearaxle = game.world.get_bodies_at_pos(rearwheel) + frontaxle = game.world.get_bodies_at_pos(frontwheel) + game.world.add.jointMotor(rearaxle[0],rearaxle[1],rearwheel) + game.world.add.jointMotor(frontaxle[0],frontaxle[1],frontwheel) + + for i in range(1,len(points)): + backlink = (points[i][0]+train[0]-1,points[i][1]+train[1]-1) + frontlink = (points[i-1][0]+1,points[i-1][1]+train[1]-1) + btrain = game.world.get_bodies_at_pos(backlink) + ftrain = game.world.get_bodies_at_pos(frontlink) + game.world.add.distanceJoint(btrain[0], ftrain[0], backlink, frontlink) diff --git a/physics.py b/physics.py index f2e38f5..e0afdf4 100644 --- a/physics.py +++ b/physics.py @@ -23,7 +23,7 @@ import olpcgames import elements from elements import Elements import tools -import bridge +from bridge import Bridge from helpers import * class PhysicsGame: @@ -35,6 +35,7 @@ class PhysicsGame: self.canvas = olpcgames.ACTIVITY.canvas self.joystickobject = None self.debug = True + # create the name --> instance map for components self.toolList = {} for c in tools.allTools: @@ -48,8 +49,9 @@ class PhysicsGame: # set up static environment self.world.add.ground() - bridge.create_world(self) - bridge.create_train(self) + self.bridge = Bridge(self) + self.bridge.create_world() + self.bridge.create_train() def run(self): self.running = True @@ -63,6 +65,9 @@ class PhysicsGame: self.currentTool.handleEvents(event) # Clear Display self.screen.fill((255,255,255)) #255 for white + + if self.world.run_physics: + self.bridge.for_each_frame() # Update & Draw World self.world.update() @@ -72,9 +77,10 @@ class PhysicsGame: self.currentTool.draw() #Print all the text on the screen - text = self.font.render("Current Tool: "+self.currentTool.name, True, (255,255,255)) + text = self.font.render("Total Cost: %d" % self.bridge.cost, True, (0,0,0)) textpos = text.get_rect(left=700,top=7) self.screen.blit(text,textpos) + # Flip Display pygame.display.flip() diff --git a/tools.py b/tools.py index 07d6f49..c23870e 100644 --- a/tools.py +++ b/tools.py @@ -4,6 +4,7 @@ # By Alex Levenson #================================================================== import pygame +from elements import box2d from pygame.locals import * from helpers import * from inspect import getmro @@ -92,6 +93,9 @@ class Tool(object): # default cancel doesn't do anything pass + def to_b2vec(self, pt): + return self.game.world.add.to_b2vec(pt) + # The circle creation tool class CircleTool(Tool): name = "circle" @@ -149,7 +153,8 @@ class BoxTool(Tool): elif event.type == MOUSEBUTTONUP: if event.button == 1 and self.pt1!=None: if self.rect.width > 10 and self.rect.height > 10: # elements doesn't like small shapes :( - self.game.world.add.rect(self.rect.center, self.rect.width/2, self.rect.height/2, dynamic=True, density=1.0, restitution=0.16, friction=0.5) + self.game.world.add.rect(self.rect.center, self.rect.width/2, self.rect.height/2, dynamic=True, density=1.0, restitution=0.16, friction=0.5) + self.game.bridge.box_added() self.pt1 = None def draw(self): @@ -164,126 +169,6 @@ class BoxTool(Tool): self.pt1 = None self.rect = None -# The triangle creation tool -class TriangleTool(Tool): - name = "triangle" - icon = "triangle" - toolTip = "Triangle" - - def __init__(self,gameInstance): - self.game = gameInstance - self.name = "Triangle" - self.pt1 = None - self.vertices = None - def handleEvents(self,event): - #look for default events, and if none are handled then try the custom events - if not super(TriangleTool,self).handleEvents(event): - if event.type == MOUSEBUTTONDOWN: - if event.button == 1: - self.pt1 = pygame.mouse.get_pos() - elif event.type == MOUSEBUTTONUP: - if event.button == 1 and self.pt1!= None: - if distance(self.pt1,pygame.mouse.get_pos()) > 15: # elements doesn't like tiny shapes :( - self.game.world.add.convexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5) - self.pt1 = None - self.vertices = None - def draw(self): - # draw a triangle from pt1 to mouse - if self.pt1 != None: - self.vertices = constructTriangleFromLine(self.pt1,pygame.mouse.get_pos()) - pygame.draw.polygon(self.game.screen, (100,180,255),self.vertices, 3) - pygame.draw.line(self.game.screen,(100,180,255),self.pt1,pygame.mouse.get_pos(),1) - - def cancel(self): - self.pt1 = None - self.vertices = None - -# The Polygon creation tool -class PolygonTool(Tool): - name = "polygon" - icon = "polygon" - toolTip = "Polygon" - - def __init__(self,gameInstance): - self.game = gameInstance - self.name = "Polygon" - self.vertices = None - def handleEvents(self,event): - #look for default events, and if none are handled then try the custom events - if not super(PolygonTool,self).handleEvents(event): - if event.type == MOUSEBUTTONDOWN: - if event.button == 1: - if not self.vertices: - self.vertices=[event.pos] - elif distance(event.pos,self.vertices[0]) < 15: - #self.vertices.append(self.vertices[0]) #connect the polygon - gons = decomposePoly(self.vertices) - for g in gons: - self.game.world.add.convexPoly(g, dynamic=True, density=1.0, restitution=0.16, friction=0.5) - #self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5) - self.vertices = None - else: - self.vertices.append(event.pos) - if event.button == 3: - if self.vertices: - self.vertices.append(event.pos) - self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5) - self.vertices = None - - def draw(self): - # draw the poly being created - if self.vertices: - for i in range(len(self.vertices)-1): - pygame.draw.line(self.game.screen,(100,180,255),self.vertices[i],self.vertices[i+1],3) - pygame.draw.line(self.game.screen,(100,180,255),self.vertices[-1],pygame.mouse.get_pos(),3) - pygame.draw.circle(self.game.screen,(100,180,255),self.vertices[0],15,3) - - def cancel(self): - self.vertices = None - -# The magic pen tool -class MagicPenTool(Tool): - name = "magicpen" - icon = "magicpen" - toolTip = "Magic Pen" - - def __init__(self,gameInstance): - self.game = gameInstance - self.name = "Magic Pen" - self.vertices = None - def handleEvents(self,event): - #look for default events, and if none are handled then try the custom events - if not super(MagicPenTool,self).handleEvents(event): - if event.type == MOUSEBUTTONDOWN: - if event.button == 1: - if not self.vertices: - self.vertices=[event.pos] - elif distance(event.pos,self.vertices[0]) < 15: - self.vertices.append(self.vertices[0]) #connect the polygon - self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5) - self.vertices = None - else: - self.vertices.append(event.pos) - elif event.type == MOUSEBUTTONUP: - if event.button == 1: - if self.vertices: - self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5) - self.vertices = None - elif event.type == MOUSEMOTION: - if self.vertices: - self.vertices.append(event.pos) - - def draw(self): - # draw the poly being created - if self.vertices: - for i in range(len(self.vertices)-1): - pygame.draw.line(self.game.screen,(100,180,255),self.vertices[i],self.vertices[i+1],3) - pygame.draw.line(self.game.screen,(100,180,255),self.vertices[-1],pygame.mouse.get_pos(),3) - pygame.draw.circle(self.game.screen,(100,180,255),self.vertices[0],15,3) - - def cancel(self): - self.vertices = None - # The grab tool class GrabTool(Tool): name = "grab" @@ -313,6 +198,7 @@ class GrabTool(Tool): def cancel(self): self.game.world.add.remove_mouseJoint() +<<<<<<< HEAD:tools.py # The joint tool class JointTool(Tool): name = "joint" @@ -369,6 +255,8 @@ class JointTool(Tool): def cancel(self): self.jb1 = self.jb2 = self.jb1pos = self.jb2pos = None +======= +>>>>>>> 901a8a638a92b2138b6ce27dd7e90b3b3b4d1833:tools.py # The destroy tool class DestroyTool(Tool): name = "destroy" @@ -401,41 +289,38 @@ class DestroyTool(Tool): def cancel(self): self.vertices = None - # The joystick tool -class JoystickTool(Tool): - name = "joystick" - icon = "magicpen" # for now - toolTip = "Joystick" - +# The joint tool +class BridgeJointTool(Tool): + name = "bridgejoint" + icon = "joint" + toolTip = "Bridge Joint" + def __init__(self,gameInstance): self.game = gameInstance - self.name = "Joystick" - self.vertices = None - #self.joystickobject + self.name = "Bridge Joint" + self.jb1 = self.jb2 = self.jb1pos = self.jb2pos = None def handleEvents(self,event): #look for default events, and if none are handled then try the custom events - super(JoystickTool,self).handleEvents(event) - if pygame.mouse.get_pressed()[0]: - if not self.vertices: - self.vertices = [] - self.vertices.append(pygame.mouse.get_pos()) - if len(self.vertices) > 10: - self.vertices.pop(0) - self.game.joystickobject = self.game.world.get_bodies_at_pos(pygame.mouse.get_pos()) - if self.game.joystickobject: - print "hi1" - #self.game.world.world.DestroyBody(self.joystickobject[0]) - elif event.type == MOUSEBUTTONUP and event.button == 1: - self.cancel() - def draw(self): - # draw the trail - if self.vertices: - if len(self.vertices) > 1: - pygame.draw.lines(self.game.screen,(255,0,0),False,self.vertices,3) + if super(BridgeJointTool,self).handleEvents(event): + return + if event.type != MOUSEBUTTONUP or event.button != 1: + return - def cancel(self): - self.vertices = None + bodies = self.game.world.get_bodies_at_pos(event.pos, + include_static=True) + if not bodies or len(bodies) != 2: + return + + jointDef = box2d.b2RevoluteJointDef() + jointDef.Initialize(bodies[0], bodies[1], self.to_b2vec(event.pos)) + joint = self.game.world.world.CreateJoint(jointDef) + self.game.bridge.joint_added(joint) + def draw(self): + return + + def cancel(self): + self.jb1 = self.jb2 = self.jb1pos = self.jb2pos = None def getAllTools(): this_mod = __import__(__name__) -- cgit v0.9.1