def pickle_load(self, fn, set_vars=True, additional_vars=[]): """ Load the pickled world in file fn. additional_vars is a dictionary to be populated with the loaded variables. """ import cPickle as pickle try: world, variables = pickle.load(open(fn, 'rb')) world = world._pickle_finalize() variables = box2d.pickle_fix(world, variables, 'load') except Exception as s: print 'Error while loading world: ', s return self.world = world if set_vars: # reset the additional saved variables: for var, value in variables.items(): if hasattr(self, var): setattr(self, var, value) else: print 'Unknown property %s=%s' % (var, value) print 'Loaded from %s' % fn return variables
def get_bodies_at_pos(self, search_point, include_static=False, area=0.01): """ Check if given point (screen coordinates) is inside any body. If yes, return all found bodies, if not found return False """ sx, sy = self.to_world(search_point) sx /= self.ppm sy /= self.ppm f = area / self.camera.scale_factor AABB = box2d.b2AABB() AABB.lowerBound = (sx - f, sy - f) AABB.upperBound = (sx + f, sy + f) query_cb = Query_CB() self.world.QueryAABB(query_cb, AABB) bodylist = [] for s in query_cb.fixtures: body = s.body if body is None: continue if not include_static: if body.type == box2d.b2_staticBody or body.mass == 0.0: continue if s.TestPoint((sx, sy)): bodylist.append(body) return bodylist
def __init__(self, screen_size, gravity=(0.0, -9.0), ppm=100.0, renderer='pygame'): """ Init the world with boundaries and gravity, and init colors. Parameters: screen_size .. (w, h) -- screen size in pixels [int] gravity ...... (x, y) in m/s^2 [float] default: (0.0, -9.0) ppm .......... pixels per meter [float] default: 100.0 renderer ..... which drawing method to use (str) default: 'pygame' Return: class Elements() """ self.set_screenSize(screen_size) self.set_drawingMethod(renderer) # Create Subclasses self.add = add_objects.Add(self) self.callbacks = callbacks.CallbackHandler(self) self.camera = camera.Camera(self) # Gravity + Bodies will sleep on outside self.gravity = gravity self.doSleep = True self.PIN_MOTOR_RADIUS = 2 # Create the World self.world = box2d.b2World(self.gravity, self.doSleep) bodyDef = box2d.b2BodyDef() self.world.groundBody = self.world.CreateBody(bodyDef) # Init Colors self.init_colors() # Set Pixels per Meter self.ppm = ppm
def pickle_save(self, fn, additional_vars={}): import cPickle as pickle self.add.remove_mouseJoint() if not additional_vars and hasattr(self, '_pickle_vars'): additional_vars = dict((var, getattr(self, var)) for var in self._pickle_vars) save_values = [self.world, box2d.pickle_fix(self.world, additional_vars, 'save')] try: pickle.dump(save_values, open(fn, 'wb')) except Exception as s: print 'Pickling failed: ', s return print 'Saved to %s' % fn
def pickle_save(self, fn, additional_vars={}): import cPickle as pickle self.add.remove_mouseJoint() if not additional_vars and hasattr(self, '_pickle_vars'): additional_vars = dict( (var, getattr(self, var)) for var in self._pickle_vars) save_values = [ self.world, box2d.pickle_fix(self.world, additional_vars, 'save') ] try: pickle.dump(save_values, open(fn, 'wb')) except Exception as s: print 'Pickling failed: ', s return print 'Saved to %s' % fn
def json_load(self, path, serialized=False): import json self.world.groundBody.userData = {"saveid": 0} f = open(path, 'r') worldmodel = json.loads(f.read()) f.close() # clean world for joint in self.world.joints: self.world.DestroyJoint(joint) for body in self.world.bodies: if body != self.world.groundBody: self.world.DestroyBody(body) # load bodies for body in worldmodel['bodylist']: bodyDef = box2d.b2BodyDef() if body['dynamic']: bodyDef.type = box2d.b2_dynamicBody bodyDef.position = body['position'] bodyDef.userData = body['userData'] bodyDef.angle = body['angle'] newBody = self.world.CreateBody(bodyDef) # _logger.debug(newBody) newBody.angularVelocity = body['angularVelocity'] newBody.linearVelocity = body['linearVelocity'] if 'shapes' in body: for shape in body['shapes']: if shape['type'] == 'polygon': polyDef = box2d.b2FixtureDef() polyShape = box2d.b2PolygonShape() polyShape.vertices = shape['vertices'] polyDef.shape = polyShape polyDef.density = shape['density'] polyDef.restitution = shape['restitution'] polyDef.friction = shape['friction'] newBody.CreateFixture(polyDef) if shape['type'] == 'circle': circleDef = box2d.b2FixtureDef() circleShape = box2d.b2CircleShape() circleShape.radius = shape['radius'] circleShape.pos = shape['localPosition'] circleDef.shape = circleShape circleDef.density = shape['density'] circleDef.restitution = shape['restitution'] circleDef.friction = shape['friction'] newBody.CreateFixture(circleDef) for joint in worldmodel['jointlist']: if joint['type'] == 'distance': jointDef = box2d.b2DistanceJointDef() body1 = self.getBodyWithSaveId(joint['body1']) anch1 = joint['anchor1'] body2 = self.getBodyWithSaveId(joint['body2']) anch2 = joint['anchor2'] jointDef.collideConnected = joint['collideConnected'] jointDef.Initialize(body1, body2, anch1, anch2) jointDef.userData = joint['userData'] self.world.CreateJoint(jointDef) if joint['type'] == 'revolute': jointDef = box2d.b2RevoluteJointDef() body1 = self.getBodyWithSaveId(joint['body1']) body2 = self.getBodyWithSaveId(joint['body2']) anchor = joint['anchor'] jointDef.Initialize(body1, body2, anchor) jointDef.userData = joint['userData'] jointDef.motorEnabled = joint['enableMotor'] jointDef.motorSpeed = joint['motorSpeed'] jointDef.maxMotorTorque = joint['maxMotorTorque'] self.world.CreateJoint(jointDef) self.additional_vars = {} addvars = {} for (k, v) in worldmodel['additional_vars'].items(): addvars[k] = v if serialized and 'trackinfo' in addvars: trackinfo = addvars['trackinfo'] for key, info in trackinfo.iteritems(): if not info[3]: addvars['trackinfo'][key][0] = \ self.getBodyWithSaveId(info[0]) addvars['trackinfo'][key][1] = \ self.getBodyWithSaveId(info[1]) else: addvars['trackinfo'][key][0] = None addvars['trackinfo'][key][1] = None self.additional_vars = addvars for body in self.world.bodies: del body.userData['saveid'] # remove temporary data
def draw(self): """ If a drawing method is specified, this function passes the objects to the module in pixels. Return: True if the objects were successfully drawn False if the renderer was not set or another error occurred """ self.callbacks.start(CALLBACK_DRAWING_START) # No need to run through the loop if there's no way to draw if not self.renderer: return False if self.camera.track_body: # Get Body Center p1 = self.camera.track_body.GetWorldCenter() # Center the Camera There, False = Don't stop the tracking self.camera.center(self.to_screen((p1.x * self.ppm, p1.y * self.ppm)), stopTrack=False) # Walk through all known elements self.renderer.start_drawing() for body in self.world.bodies: xform = body.transform shape = body.fixtures angle = body.angle if shape: userdata = body.userData if 'color' in userdata: clr = userdata['color'] else: clr = self.colors[0] for shape in body.fixtures: type_ = shape.type if type_ == box2d.b2Shape.e_circle: position = box2d.b2Mul(xform, shape.shape.pos) pos = self.to_screen((position.x * self.ppm, position.y * self.ppm)) self.renderer.draw_circle( clr, pos, self.meter_to_screen(shape.shape.radius), angle) elif type_ == box2d.b2Shape.e_polygon: points = [] for v in shape.shape.vertices: pt = box2d.b2Mul(xform, v) x, y = self.to_screen((pt.x * self.ppm, pt.y * self.ppm)) points.append([x, y]) self.renderer.draw_polygon(clr, points) else: print "unknown shape type:%d" % shape.type for joint in self.world.joints: p2 = joint.anchorA p2 = self.to_screen((p2.x * self.ppm, p2.y * self.ppm)) p1 = joint.anchorB p1 = self.to_screen((p1.x * self.ppm, p1.y * self.ppm)) if isinstance(joint, box2d.b2RevoluteJoint): self.renderer.draw_circle((255, 255, 255), p1, self.PIN_MOTOR_RADIUS, 0) else: self.renderer.draw_lines((0, 0, 0), False, [p1, p2], 3) self.callbacks.start(CALLBACK_DRAWING_END) self.renderer.after_drawing() return True
def draw(self): """ If a drawing method is specified, this function passes the objects to the module in pixels. Return: True if the objects were successfully drawn False if the renderer was not set or another error occurred """ self.callbacks.start(CALLBACK_DRAWING_START) # No need to run through the loop if there's no way to draw if not self.renderer: return False if self.camera.track_body: # Get Body Center p1 = self.camera.track_body.GetWorldCenter() # Center the Camera There, False = Don't stop the tracking self.camera.center(self.to_screen( (p1.x * self.ppm, p1.y * self.ppm)), stopTrack=False) # Walk through all known elements self.renderer.start_drawing() for body in self.world.bodies: xform = body.transform shape = body.fixtures angle = body.angle if shape: userdata = body.userData if 'color' in userdata: clr = userdata['color'] else: clr = self.colors[0] for shape in body.fixtures: type_ = shape.type if type_ == box2d.b2Shape.e_circle: position = box2d.b2Mul(xform, shape.shape.pos) pos = self.to_screen( (position.x * self.ppm, position.y * self.ppm)) self.renderer.draw_circle( clr, pos, self.meter_to_screen(shape.shape.radius), angle) elif type_ == box2d.b2Shape.e_polygon: points = [] for v in shape.shape.vertices: pt = box2d.b2Mul(xform, v) x, y = self.to_screen( (pt.x * self.ppm, pt.y * self.ppm)) points.append([x, y]) self.renderer.draw_polygon(clr, points) else: print "unknown shape type:%d" % shape.type for joint in self.world.joints: p2 = joint.anchorA p2 = self.to_screen((p2.x * self.ppm, p2.y * self.ppm)) p1 = joint.anchorB p1 = self.to_screen((p1.x * self.ppm, p1.y * self.ppm)) if isinstance(joint, box2d.b2RevoluteJoint): self.renderer.draw_circle((255, 255, 255), p1, self.PIN_MOTOR_RADIUS, 0) else: self.renderer.draw_lines((0, 0, 0), False, [p1, p2], 3) self.callbacks.start(CALLBACK_DRAWING_END) self.renderer.after_drawing() return True