def genJunctions(self): self.pin_ra_c = pymunk.PinJoint(self.right_arm.body, self.corpse.body, (0, 0), (0, 30 * self.size)) self.pin_ra_c_r = pymunk.DampedRotarySpring(self.right_arm.body, self.right_arm.body_joint, -0.15, 20000000, 900000) self.pin_ra_c.error_bias = pow(0.7, 60.0) self.pin_la_c = pymunk.PinJoint(self.left_arm.body, self.corpse.body, (0, 0), (0, 30 * self.size)) self.pin_la_c_r = pymunk.DampedRotarySpring(self.left_arm.body, self.left_arm.body_joint, -0.15, 20000000, 900000) self.pin_la_c.error_bias = pow(0.7, 60.0) self.pin_rl_c = pymunk.PinJoint(self.right_leg.body, self.corpse.body, (0, 0), (0, 0)) self.pin_rl_c_r = pymunk.DampedRotarySpring(self.right_leg.body, self.right_leg.body_joint, -0.15, 20000000, 900000) self.pin_rl_c.error_bias = pow(0.7, 60.0) self.pin_ll_c = pymunk.PinJoint(self.left_leg.body, self.corpse.body, (0, 0), (0, 0)) self.pin_ll_c_r = pymunk.DampedRotarySpring(self.left_leg.body, self.left_leg.body_joint, 10, 1, 1) self.pin_ll_c.error_bias = pow(0.7, 60.0)
def __init__(self, space, shape1, shape2, angle, stiffness, damping): # Associate the joint with the location of one of the bodies so # it is removed when that body is out of the simulation self.body = shape1.body self.shape = pymunk.DampedRotarySpring(shape1.body, shape2.body, math.radians(-angle), stiffness, damping) super().__init__() space.add(self.shape)
def build(space, group): # type: (pymunk.Space, pygame.sprite.AbstractGroup) -> CatModel """ Builds our unicycle cat. :param space: The pymunk space to put the cat in. :param group: The pygame sprite group to put the cat in. """ scale = 2 normal_rect = pygame.Rect(0, 0, 32 * scale, 40 * scale) cat_model = CatModel() sprites = [] pymunk_objects = [] filter1 = pymunk.ShapeFilter(group=0b000001) # Main body body_body = pymunk.Body(0.00001, pymunk.inf) body_body.position = normal_rect.topleft cat_model.main_body = body_body pymunk_objects.append(body_body) # seat seat_body = build_seat(filter1, normal_rect, pymunk_objects, sprites) # build feet cat_model.feet, feet_sprite = build_feet(filter1, normal_rect, pymunk_objects, body_body, seat_body) sprites.append(feet_sprite) # Add motor cat_model.motor = pymunk.SimpleMotor(body_body, cat_model.feet, 0.0) pymunk_objects.append(cat_model.motor) # cat cat_body, cat_rect = build_cat(normal_rect, pymunk_objects, sprites) # hold cat the the seat spring = pymunk.DampedSpring(seat_body, cat_body, normal_rect.midtop, cat_rect.midbottom, 0, 1, 0) pymunk_objects.append(spring) # tilt corrector spring = pymunk.DampedRotarySpring(body_body, seat_body, radians(0), 60000, 20000) spring.collide_bodies = False pymunk_objects.append(spring) cat_model.sprites = sprites cat_model.pymunk_objects = pymunk_objects space.add(pymunk_objects) group.add(*sprites) return cat_model
def create_physics(self): constraint = pymunk.DampedRotarySpring( self.a.body, self.b.body, rest_angle=self.rest_angle, stiffness=self.stiffness, damping=self.damping, ) self._constraint = constraint self.engine.space.add(constraint)
def testPickle(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.DampedRotarySpring(a, b, 1, 2, 3) s = pickle.dumps(j) j2 = pickle.loads(s) self.assertEqual(j.rest_angle, j2.rest_angle) self.assertEqual(j.stiffness, j2.stiffness) self.assertEqual(j.damping, j2.damping) self.assertEqual(j.a.mass, j2.a.mass) self.assertEqual(j.b.mass, j2.b.mass)
def testDampedRotarySpringCallback(self): a,b = p.Body(10,10), p.Body(20,20) j = p.DampedRotarySpring(a,b, 0.4, 12,5) def f(self, relative_angle): return 1 j.torque_func = f s = p.Space() s.add(a,b,j) a.apply_impulse((10,0), (0,10)) a.apply_impulse((-10,0), (0,-10)) for x in range(100): s.step(0.1) self.assertAlmostEqual(a.angle-b.angle,-29.3233997)
def __init__(self, app, pos, angle): self.app = app rads = angle / -57.3 hw = self.size[1] * .5 self.body = pymunk.Body() self.body.position = pos[::2] self.body.angle = rads static_body = self.app.physics.space.static_body self.collider = pymunk.Poly.create_box(self.body, self.size) self.collider.y = pos[1] self.collider.height = self.height self.collider.mass = .5 self.collider.collision_type = physics.STATIC mask = pymunk.ShapeFilter.ALL_MASKS ^ physics.STATIC_FILTER ^ physics.DOOR_FILTER self.collider.filter = pymunk.ShapeFilter(categories=physics.DOOR_FILTER, mask=mask) hinge_dx = math.sin(-rads) * -hw hinge_dy = math.cos(-rads) * -hw self.hinge_joint = pymunk.PivotJoint(static_body, self.body, (pos[0] + hinge_dx, pos[2] + hinge_dy)) self.rotary_spring = pymunk.DampedRotarySpring(static_body, self.body, -rads, 5, 5) min_angle = rads - self.swing_angle max_angle = rads + self.swing_angle self.rotary_limit = pymunk.RotaryLimitJoint(static_body, self.body, min_angle, max_angle) self.app.physics.space.add(self.body, self.collider, self.hinge_joint, self.rotary_spring, self.rotary_limit) self.canvas = Canvas() with self.canvas: PushMatrix() self.pos = Translate(*pos) self.rot = Rotate(0, 0, 1, 0) self.app.graphic_data.draw_mesh('models/door', self.canvas, texture='door.png') PopMatrix()
def generateFlipper(space): # Construction des deux objetcs flippers coorBodyFlippers = [(-5, -10), (0, -5), (-85, -2), (-90, 5), (-85, 12), (-5, 10), (0, 5)] mass = 100 moment = pymunk.moment_for_poly(mass, coorBodyFlippers) right_flipper = pymunk.Body(mass, moment) right_flipper.position = 729,100 right_flipper_object = pymunk.Poly(right_flipper, coorBodyFlippers) right_flipper_object.color = THECOLORS["deepskyblue"] space.add(right_flipper, right_flipper_object) left_flipper = pymunk.Body(mass, moment) left_flipper.position = 513,101 left_flipper_object = pymunk.Poly(left_flipper, [(-x, y) for x, y in coorBodyFlippers]) left_flipper_object.color = THECOLORS["deepskyblue"] space.add(left_flipper, left_flipper_object) right_flipper_joint_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) right_flipper_joint_body.position = right_flipper.position left_flipper_joint_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) left_flipper_joint_body.position = left_flipper.position # Point de rotation des flippers joint_right = pymunk.PinJoint(right_flipper, right_flipper_joint_body, (0, 0), (0, 0)) joint_left = pymunk.PinJoint(left_flipper, left_flipper_joint_body, (0, 0), (0, 0)) juncture_right = pymunk.DampedRotarySpring(right_flipper, right_flipper_joint_body, 0.15, 15000000, 2000000) juncture_left = pymunk.DampedRotarySpring(left_flipper, left_flipper_joint_body, -0.15, 15000000, 2000000) space.add(joint_right, juncture_right) space.add(joint_left, juncture_left) # aspect physique des flippers right_flipper_object.elasticity = left_flipper_object.elasticity = 0.5 return left_flipper,right_flipper
def draw_flippers(space): # Add Flippers fp = [(20, -20), (-120, 0), (20, 20)] mass = 100 moment = pymunk.moment_for_poly(mass, fp) # right flipper r_flipper_body = pymunk.Body(mass, moment) r_flipper_body.position = 750, 10 r_flipper_shape = pymunk.Poly(r_flipper_body, fp) space.add(r_flipper_body, r_flipper_shape) r_flipper_joint_body = pymunk.Body() r_flipper_joint_body.position = r_flipper_body.position j = pymunk.PinJoint(r_flipper_body, r_flipper_joint_body, (0, 0), (0, 0)) #todo: tweak values of spring better s = pymunk.DampedRotarySpring(r_flipper_body, r_flipper_joint_body, 0.15, 20000000, 900000) space.add(j, s) # left flipper l_flipper_body = pymunk.Body(mass, moment) l_flipper_body.position = 10, 10 l_flipper_shape = pymunk.Poly(l_flipper_body, [(-x, y) for x, y in fp]) space.add(l_flipper_body, l_flipper_shape) l_flipper_joint_body = pymunk.Body() l_flipper_joint_body.position = l_flipper_body.position j = pymunk.PinJoint(l_flipper_body, l_flipper_joint_body, (0, 0), (0, 0)) s = pymunk.DampedRotarySpring(l_flipper_body, l_flipper_joint_body, -0.15, 20000000, 900000) space.add(j, s) r_flipper_shape.group = l_flipper_shape.group = 1 r_flipper_shape.elasticity = l_flipper_shape.elasticity = 0.4 return r_flipper_body, r_flipper_shape, l_flipper_body, l_flipper_shape
def __init__(self): self.space = pm.Space() self.space.damping = 0.9 # to slow down bodies # make arms self.root0 = (0, 0) self.arm0 = Arm(self.root0, 24) self.root1 = (0, 24) self.arm1 = Arm(self.root1, 16) self.space.add(self.arm0.body, self.arm0.shape, self.arm1.body, self.arm1.shape) # set torques self.max_torque0 = self.arm0.body.moment self.max_torque1 = self.arm1.body.moment * 2 # torque ratio self.instant_torques = None # join arms self.pj0 = pm.PivotJoint(self.arm0.body, self.space.static_body, self.root0) self.space.add(self.pj0) self.pj1 = pm.PivotJoint(self.arm1.body, self.arm0.body, self.root1) self.space.add(self.pj1) self.spring_stiffness = 10 self.drs0 = pm.DampedRotarySpring(self.arm0.body, self.space.static_body, 0, 0, 1) self.space.add(self.drs0) self.drs1 = pm.DampedRotarySpring(self.arm1.body, self.arm0.body, 0, 0, 1) self.space.add(self.drs1) # canvas 28 * 28 self.canvas = Canvas() self.cache_point_g = None self.cache_point_b = None self.cache_point_m = None self.cache_point_y = None self.cache_point_r = None self.cache_point_c = None self.cache_point_k = None
def _setup_extra_bodies(self): # Googly eye control bodies & joints. self.pupil_bodies = [] for _ in range(2): eye_mass = self.mass / 10 eye_radius = self.radius eye_inertia = pm.moment_for_circle(eye_mass, 0, eye_radius, (0, 0)) eye_body = pm.Body(eye_mass, eye_inertia) eye_body.angle = self.init_angle eye_joint = pm.DampedRotarySpring(self.body, eye_body, 0, 0.1, 3e-3) eye_joint.max_bias = 3.0 eye_joint.max_force = 0.001 self.pupil_bodies.append(eye_body) self.add_to_space(eye_joint) self.extra_bodies.extend(self.pupil_bodies)
def __init__(self, ori, *args, **kwargs): super(Bat, self).__init__(*args, **kwargs) self.orientation = ori # criando o bastão se acordo com o lado que será posicionado moment = pymunk.moment_for_poly(self.massa, self.forma) self.body = pymunk.Body(self.massa, moment) self.body.position = self.x, self.y self.shape = pymunk.Poly(self.body, [(ori*x, y) for x, y in self.forma]) #o valor de ori torna o x positivo ou negativo # criando o ponto em que o bastão é fixado self.jointBody = pymunk.Body(body_type=pymunk.Body.KINEMATIC) self.jointBody.position = self.body.position self.j = pymunk.PivotJoint(self.body, self.jointBody, (0, 0), (0, 0)) self.s = pymunk.DampedRotarySpring(self.body, self.jointBody, 0.15*ori, 20000000, 900000) # atribuindo algumas caracteristcas ao bastão self.shape.group = 1 self.shape.elasticity = 0.9 self.status = "NORMAL"
def addToSpace(self, space): # samples for door # each sample contains information about surface point, normal and maximum radius of contacting body self.door_samples = [] for t in np.linspace(0.1, 0.9, 5, endpoint=True): self.door_samples.append( (Vec2d(self.x_mult * self.length/2.0 * t, -self.width/2.0), Vec2d(0,-1), float("inf")) ) radius_tab = [ 100, 50, 15, 5, 5 ] idx = 0 for t in np.linspace(0.1, 0.9, 5, endpoint=True): self.door_samples.append( (Vec2d(self.x_mult * self.length/2.0 * t, self.width/2.0), Vec2d(0,1), radius_tab[idx]) ) idx += 1 self.door_samples.append( (Vec2d(self.x_mult * (self.length/2.0*0.8 - 4*2.0), 4*4.0), Vec2d(0,1), float("inf")) ) self.door_samples.append( (Vec2d(self.x_mult * (self.length/2.0*0.8 - 4*2.0), 4*4.0), Vec2d(0,-1), 5) ) mass = 10.0 moment = pymunk.moment_for_poly(mass, self.fp) self.body = pymunk.Body(mass, moment) self.body.position = self.hinge_pos #t5 self.body.angle = self.rotation + self.init_angle self.door_shape = pymunk.Poly(self.body, self.fp, radius=1) self.door_shape.group = 1 # handle self.handle_shape1 = pymunk.Segment(self.body, Vec2d(self.x_mult * (self.length/2.0*0.8), self.width*0.5), Vec2d(self.x_mult * (self.length/2.0*0.8), self.width*4.0), self.width) self.handle_shape1.group = 1 self.handle_shape2 = pymunk.Segment(self.body, Vec2d(self.x_mult * (self.length/2.0*0.8 - self.width*4.0), self.width*4.0), Vec2d(self.x_mult * (self.length/2.0*0.8), self.width*4.0), self.width) self.handle_shape2.group = 1 space.add(self.body, self.door_shape, self.handle_shape1, self.handle_shape2) j = pymunk.PivotJoint(self.body, space.static_body, self.body.position) s = pymunk.DampedRotarySpring(self.body, space.static_body, 0, 0, 90000) space.add(j, s) j2 = pymunk.RotaryLimitJoint(self.body, space.static_body, -(self.rotation+self.limits[1]), -(self.rotation+self.limits[0])) space.add(j2)
def fill_space(space, custom_color=(255, 255, 0, 255)): captions = [] ### Static captions.append(((50, 680), "Static Shapes")) #Static Segments segments = [ pymunk.Segment(space.static_body, (10, 400), (10, 600), 0), pymunk.Segment(space.static_body, (20, 400), (20, 600), 1), pymunk.Segment(space.static_body, (30, 400), (30, 600), 3), pymunk.Segment(space.static_body, (50, 400), (50, 600), 5) ] space.add(segments) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (40, 630) b.angle = 3.14 / 7 s = pymunk.Segment(b, (-30, 0), (30, 0), 2) space.add(s) # Static Circles b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 630) s = pymunk.Circle(b, 10) space.add(s) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 630) s = pymunk.Circle(b, 10, (-30, 0)) space.add(s) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 560) b.angle = 3.14 / 4 s = pymunk.Circle(b, 40) space.add(s) # Static Polys b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 460) b.angle = 3.14 / 4 s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)]) space.add(s) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (120, 500) t = pymunk.Transform(ty=-100) s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)], t, radius=3) space.add(s) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (50, 430) t = pymunk.Transform(ty=-100) s = pymunk.Poly(b, [(0, -50), (50, 0), (30, 50), (-30, 50), (-50, 0)], t) space.add(s) ### Kinematic captions.append(((220, 680), "Kinematic Shapes")) # Kinematic Segments b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) segments = [ pymunk.Segment(b, (180, 400), (180, 600), 0), pymunk.Segment(b, (190, 400), (190, 600), 1), pymunk.Segment(b, (200, 400), (200, 600), 3), pymunk.Segment(b, (220, 400), (220, 600), 5) ] space.add(segments) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (210, 630) b.angle = 3.14 / 7 s = pymunk.Segment(b, (-30, 0), (30, 0), 2) space.add(s) # Kinematic Circles b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 630) s = pymunk.Circle(b, 10) space.add(s) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 630) s = pymunk.Circle(b, 10, (-30, 0)) space.add(s) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 560) b.angle = 3.14 / 4 s = pymunk.Circle(b, 40) space.add(s) # Kinematic Polys b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 460) b.angle = 3.14 / 4 s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)]) space.add(s) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (290, 500) t = pymunk.Transform(ty=-100) s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)], t, radius=3) space.add(s) b = pymunk.Body(body_type=pymunk.Body.KINEMATIC) b.position = (230, 430) t = pymunk.Transform(ty=-100) s = pymunk.Poly(b, [(0, -50), (50, 0), (30, 50), (-30, 50), (-50, 0)], t) space.add(s) ### Dynamic captions.append(((390, 680), "Dynamic Shapes")) #Dynamic Segments b = pymunk.Body(1, 1) segments = [ pymunk.Segment(b, (350, 400), (350, 600), 0), pymunk.Segment(b, (360, 400), (360, 600), 1), pymunk.Segment(b, (370, 400), (370, 600), 3), pymunk.Segment(b, (390, 400), (390, 600), 5), ] space.add(segments) b = pymunk.Body(1, 1) b.position = (380, 630) b.angle = 3.14 / 7 s = pymunk.Segment(b, (-30, 0), (30, 0), 2) space.add(s) # Dynamic Circles b = pymunk.Body(1, 1) b.position = (460, 630) s = pymunk.Circle(b, 10) space.add(s) b = pymunk.Body(1, 1) b.position = (460, 630) s = pymunk.Circle(b, 10, (-30, 0)) space.add(s) b = pymunk.Body(1, 1) b.position = (460, 560) b.angle = 3.14 / 4 s = pymunk.Circle(b, 40) space.add(s) # Dynamic Polys b = pymunk.Body(1, 1) b.position = (460, 460) b.angle = 3.14 / 4 s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)]) space.add(s) b = pymunk.Body(1, 1) b.position = (460, 500) s = pymunk.Poly(b, [(0, -25), (30, 25), (-30, 25)], pymunk.Transform(ty=-100), radius=3) space.add(s) b = pymunk.Body(1, 1) b.position = (400, 430) s = pymunk.Poly(b, [(0, -50), (50, 0), (30, 50), (-30, 50), (-50, 0)], pymunk.Transform(ty=-100)) space.add(s) ###Constraints # PinJoints captions.append(((560, 660), "Pin Joints")) a = pymunk.Body(1, 1) a.position = (550, 600) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (650, 620) sb = pymunk.Circle(b, 20) j = pymunk.PinJoint(a, b) space.add(sa, sb, a, b, j) a = pymunk.Body(1, 1) a.position = (550, 550) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (650, 570) sb = pymunk.Circle(b, 20) j = pymunk.PinJoint(a, b, anchor_a=(0, 20), anchor_b=(0, -20)) space.add(sa, sb, a, b, j) # SlideJoints captions.append(((560, 490), "Slide Joint")) a = pymunk.Body(1, 1) a.position = (550, 430) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (650, 450) sb = pymunk.Circle(b, 20) j = pymunk.SlideJoint(a, b, anchor_a=(0, 20), anchor_b=(0, -20), min=10, max=30) space.add(sa, sb, a, b, j) # PivotJoints captions.append(((560, 390), "Pivot Joint")) a = pymunk.Body(1, 1) a.position = (550, 330) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (650, 350) sb = pymunk.Circle(b, 20) j = pymunk.PivotJoint(a, b, (600, 320)) space.add(sa, sb, a, b, j) # GrooveJoints captions.append(((760, 660), "Groove Joint")) a = pymunk.Body(1, 1) a.position = (750, 600) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 620) sb = pymunk.Circle(b, 20) j = pymunk.GrooveJoint(a, b, (790, 610), (790, 620), (840, 620)) space.add(sa, sb, a, b, j) # DampedSpring captions.append(((760, 550), "Damped Spring")) a = pymunk.Body(1, 1) a.position = (750, 480) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 500) sb = pymunk.Circle(b, 20) j = pymunk.DampedSpring(a, b, (0, 0), (0, 10), 100, 1, 1) space.add(sa, sb, a, b, j) # DampedRotarySpring captions.append(((740, 430), "Damped Rotary Spring")) a = pymunk.Body(1, 1) a.position = (750, 350) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 380) sb = pymunk.Circle(b, 20) j = pymunk.DampedRotarySpring(a, b, 10, 1, 1) space.add(sa, sb, a, b, j) # RotaryLimitJoint captions.append(((740, 300), "Rotary Limit Joint")) a = pymunk.Body(1, 1) a.position = (750, 220) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 250) sb = pymunk.Circle(b, 20) j = pymunk.RotaryLimitJoint(a, b, 1, 2) b.angle = 3 space.add(sa, sb, a, b, j) # RatchetJoint captions.append(((740, 170), "Ratchet Joint")) a = pymunk.Body(1, 1) a.position = (750, 100) sa = pymunk.Circle(a, 20) b = pymunk.Body(1, 1) b.position = (850, 120) sb = pymunk.Circle(b, 20) j = pymunk.RatchetJoint(a, b, 1, 0.1) b.angle = 3 space.add(sa, sb, a, b, j) # GearJoint and SimpleMotor omitted since they are similar to the already # added joints # TODO: more stuff here :) ### Other # Objects in custom color captions.append(((150, 150), "Custom Color (static & dynamic)")) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (200, 200) s = pymunk.Circle(b, 40) s.color = custom_color space.add(s) b = pymunk.Body(1, 1) b.position = (300, 200) s = pymunk.Circle(b, 40) s.color = custom_color space.add(s) # Collision captions.append(((450, 150), "Collisions")) b = pymunk.Body(body_type=pymunk.Body.STATIC) b.position = (470, 200) s = pymunk.Circle(b, 40) space.add(s) b = pymunk.Body(1, 1) b.position = (500, 250) s = pymunk.Circle(b, 40) space.add(s) # Sleeping captions.append(((50, 150), "Sleeping")) b = pymunk.Body(1, 1) b.position = (75, 200) space.sleep_time_threshold = 0.01 s = pymunk.Circle(b, 40) space.add(s, b) b.sleep() space.step(0.000001) return captions
def add_damped_rotary_spring(space, body1, body2, rest_angle, stiffness, damping): damped_rotatory_spring = pymunk.DampedRotarySpring(body1, body2, rest_angle, stiffness, damping) space.add(damped_rotatory_spring) return damped_rotatory_spring
def testDampedRotarySpring(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.DampedRotarySpring(a, b, 0.4, 12, 5) self.assertEqual(j.rest_angle, 0.4) self.assertEqual(j.stiffness, 12) self.assertEqual(j.damping, 5)
#FLIPPER rbar = [(27, -16), (-90, 0), (15, 10)] lbar = [(-27, -16), (90, 0), (-15, 10)] mass = 100 mo = pymunk.moment_for_poly(mass, rbar) r_bar_body = pymunk.Body(mass, mo) r_bar_body.position = 710, 74 r_bar_form = pymunk.Poly(r_bar_body, rbar) r_bar_form.color = pygame.color.THECOLORS["white"] space.add(r_bar_body, r_bar_form) r_bar_union_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) r_bar_union_body.position = r_bar_body.position union = pymunk.PinJoint(r_bar_body, r_bar_union_body, (0, 0), (0, 0)) rotary = pymunk.DampedRotarySpring(r_bar_body, r_bar_union_body, 0.35, 9000000, 999999) space.add(union, rotary) l_bar_body = pymunk.Body(mass, mo) l_bar_body.position = 502, 74 l_bar_form = pymunk.Poly(l_bar_body, lbar) l_bar_form.color = pygame.color.THECOLORS["white"] space.add(l_bar_body, l_bar_form) l_bar_union_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) l_bar_union_body.position = l_bar_body.position union = pymunk.PinJoint(l_bar_body, l_bar_union_body, (0, 0), (0, 0)) rotary = pymunk.DampedRotarySpring(l_bar_body, l_bar_union_body, -0.35, 9000000, 999999) space.add(union, rotary) r_bar_form.group = l_bar_form.group = 1
fp = [(20, -20), (-120, 0), (20, 20)] mass = 100 moment = pymunk.moment_for_poly(mass, fp) # right flipper r_flipper_body = pymunk.Body(mass, moment) r_flipper_body.position = 450, 500 r_flipper_shape = pymunk.Poly(r_flipper_body, fp) space.add(r_flipper_body, r_flipper_shape) r_flipper_joint_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) r_flipper_joint_body.position = r_flipper_body.position j = pymunk.PinJoint(r_flipper_body, r_flipper_joint_body, (0, 0), (0, 0)) # todo: tweak values of spring better s = pymunk.DampedRotarySpring(r_flipper_body, r_flipper_joint_body, 0.15, 20000000, 900000) space.add(j, s) # left flipper l_flipper_body = pymunk.Body(mass, moment) l_flipper_body.position = 150, 500 l_flipper_shape = pymunk.Poly(l_flipper_body, [(-x, y) for x, y in fp]) space.add(l_flipper_body, l_flipper_shape) l_flipper_joint_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) l_flipper_joint_body.position = l_flipper_body.position j = pymunk.PinJoint(l_flipper_body, l_flipper_joint_body, (0, 0), (0, 0)) s = pymunk.DampedRotarySpring(l_flipper_body, l_flipper_joint_body, -0.15, 20000000, 900000) space.add(j, s)
def prep_new_run(self): """"resets the engine to a new game""" # initial_load_x = np.random.uniform(10, 15) * np.random.choice([-1, 1]) initial_load_x = 0 # initial_bumper_x = np.random.uniform(5, 7) * np.random.choice([-1, 1]) initial_bumper_x = 5.5 # initial_hoist_len = np.random.uniform(50, 60) initial_hoist_len = 60 # Make world self.space = pymunk.Space() # self.load = pymunk.Body(1000, 1000 * 30 *30) self.load = pymunk.Body(1000, 10000 * 30 * 30) self.barge = pymunk.Body(body_type=pymunk.Body.KINEMATIC) self.hook = pymunk.Body(body_type=pymunk.Body.KINEMATIC) self.space.add(self.load) self.space.add(self.barge) ## Contact shapes # give contact shapes a thickness for better stability th = 2 barge_deck = pymunk.Segment( self.barge, [self.barge_upper_left[0], self.barge_upper_left[1] + th], [self.barge_upper_right[0], self.barge_upper_right[1] + th], th) barge_deck.collision_type = 1 barge_deck.friction = self.friction self.space.add(barge_deck) # Load contact shape radius = 0.1 shape1 = pymunk.Circle(self.load, radius, self.load_lower_left) shape2 = pymunk.Circle(self.load, radius, self.load_lower_right) shape1.collision_type = 2 shape2.collision_type = 2 shape1.friction = self.friction shape2.friction = self.friction self.space.add(shape1) self.space.add(shape2) # Load contact shape bottom load_bottom_shape = pymunk.Segment(self.load, self.load_lower_left, self.load_lower_right, 0) load_bottom_shape.collision_type = 2 load_bottom_shape.friction = self.friction self.space.add(load_bottom_shape) # Load contact shape left side load_left_shape = pymunk.Segment(self.load, self.load_lower_left, self.load_upper_left, 0) load_left_shape.collision_type = 2 load_left_shape.friction = self.friction self.space.add(load_left_shape) # Load contact shape right side load_right_shape = pymunk.Segment(self.load, self.load_lower_right, self.load_upper_right, 0) load_right_shape.collision_type = 2 load_right_shape.friction = self.friction self.space.add(load_right_shape) # Guide contact shape self.bumper_lower = Vec2d(initial_bumper_x, -4) self.bumper_upper = Vec2d(initial_bumper_x, -10) bumper = pymunk.Segment( self.barge, [self.bumper_lower[0] + 2, self.bumper_lower[1]], [self.bumper_upper[0] + 2, self.bumper_upper[1]], 2) bumper.collision_type = 3 self.space.add(bumper) # spring-damper between hook and load damper = pymunk.DampedSpring(self.hook, self.load, (0, 0), self.poi, 0, 0, 5000) adamper = pymunk.DampedRotarySpring(self.hook, self.load, 0, 0, 400) self.space.add(damper, adamper) handler_barge_contact = self.space.add_collision_handler( 1, 2) # barge is type 1, load is type 2 handler_barge_contact.post_solve = self.barge_contact handler_bumper_contact = self.space.add_collision_handler( 2, 3) # bumper is type 3, load is type 2 handler_bumper_contact.post_solve = self.bumper_contact self.space.gravity = Vec2d(0, 9.81) self.space.damping = 0.98 n = int(self.t_motions / self.dt_motions) temp = self.wave_spectrum.make_time_trace(associated=self.associated, n=n, dt=self.dt_motions, locations=self.wave_location) self.wave_elevation = temp['response'] self.motions_t = temp['t'] R = temp['associated'] self.motions_sway_block = R[0] self.motions_heave_block = R[1] self.motions_302_surge = R[2] self.motions_302_heave = R[3] self.motions_302_pitch = R[4] * self.magic_pitch_factor # TODO: Temp start with stationary env # self.motions_sway_block = np.zeros((10000,)) # self.motions_heave_block = np.zeros((10000,)) # self.motions_302_surge = np.zeros((10000,)) # self.motions_302_heave = np.zeros((10000,)) # self.motions_302_pitch = np.zeros((10000,)) self.hoist_length = initial_hoist_len self.crane_sway = 0 self.barge_impulse = [] self.bumper_impulse = [] self.has_barge_contact = False self.has_bumper_contact = False self.setdown_counter = 0 self.is_done = False self.load.position = Vec2d(initial_load_x, self.hoist_length - self.poi[1]) self.time_lookup_index = 0 self.max_impact = 0
def testDamping(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.DampedRotarySpring(a, b, 0, 0, 1) self.assertEqual(j.damping, 1) j.damping = 2 self.assertEqual(j.damping, 2)
def addToSpace(self, space): line_width = 4.0 p1 = Vec2d(-self.width / 2.0, self.depth / 2.0) p2 = Vec2d(-self.width / 2.0, -self.depth / 2.0) p3 = Vec2d(self.width / 2.0, -self.depth / 2.0) p4 = Vec2d(self.width / 2.0, self.depth / 2.0) p5 = Vec2d(-self.width / 2.0, self.depth / 2.0 + line_width * 2) # left door joint t1 = p1.rotated( self.rotation ) + self.position #transform(p1, self.position, self.rotation) t2 = p2.rotated( self.rotation ) + self.position #transform(p2, self.position, self.rotation) t3 = p3.rotated( self.rotation ) + self.position #transform(p3, self.position, self.rotation) t4 = p4.rotated( self.rotation ) + self.position #transform(p4, self.position, self.rotation) t5 = p5.rotated( self.rotation ) + self.position #transform(p5, self.position, self.rotation) static = [ pymunk.Segment(space.static_body, t1, t2, line_width), pymunk.Segment(space.static_body, t2, t3, line_width), pymunk.Segment(space.static_body, t3, t4, line_width) ] for s in static: s.friction = 1. s.group = 1 space.add(static) # samples for door # each sample contains information about surface point, normal and maximum radius of contacting body self.door_samples = [] for t in np.linspace(0.1, 0.9, 5, endpoint=True): self.door_samples.append( (Vec2d(self.width / 2.0 * t, -line_width / 2.0), Vec2d(0, -1), float("inf"))) radius_tab = [100, 50, 15, 5, 5] idx = 0 for t in np.linspace(0.1, 0.9, 5, endpoint=True): self.door_samples.append( (Vec2d(self.width / 2.0 * t, line_width / 2.0), Vec2d(0, 1), radius_tab[idx])) idx += 1 self.door_samples.append((Vec2d(self.width / 2.0 * 0.8 - 4 * 2.0, 4 * 4.0), Vec2d(0, 1), float("inf"))) self.door_samples.append((Vec2d(self.width / 2.0 * 0.8 - 4 * 2.0, 4 * 4.0), Vec2d(0, -1), 5)) # polygon for left door p6 = Vec2d(0, -line_width / 2.0) p7 = Vec2d(0, line_width / 2.0) p8 = Vec2d(self.width / 2.0 - line_width, line_width / 2.0) p9 = Vec2d(self.width / 2.0 - line_width, -line_width / 2.0) # ph1 = Vec2d(self.width/2.0*0.9, line_width/2.0) # ph2 = Vec2d(self.width/2.0*0.9, line_width*4.0) # ph3 = Vec2d(self.width/2.0*0.9-line_width*4.0, line_width*4.0) # ph4 = Vec2d(self.width/2.0*0.9-line_width*4.0, line_width*3.0) # ph5 = Vec2d(self.width/2.0*0.9-line_width*1.0, line_width*3.0) # ph6 = Vec2d(self.width/2.0*0.9-line_width*1.0, line_width/2.0) self.fp = [p9, p8, p7, p6] mass = 100.0 moment = pymunk.moment_for_poly(mass, self.fp) # left door self.l_door_body = pymunk.Body(mass, moment) self.l_door_body.position = t5 self.l_door_body.angle = self.rotation l_door_shape = pymunk.Poly(self.l_door_body, self.fp, radius=1) l_door_shape.group = 1 # handle left_h1_shape = pymunk.Segment( self.l_door_body, Vec2d(self.width / 2.0 * 0.8, line_width * 0.5), Vec2d(self.width / 2.0 * 0.8, line_width * 4.0), line_width) left_h1_shape.group = 1 left_h2_shape = pymunk.Segment( self.l_door_body, Vec2d(self.width / 2.0 * 0.8 - line_width * 4.0, line_width * 4.0), Vec2d(self.width / 2.0 * 0.8, line_width * 4.0), line_width) left_h2_shape.group = 1 space.add(self.l_door_body, l_door_shape, left_h1_shape, left_h2_shape) j = pymunk.PivotJoint(self.l_door_body, space.static_body, self.l_door_body.position) s = pymunk.DampedRotarySpring(self.l_door_body, space.static_body, 0, 0, 90000) space.add(j, s) j2 = pymunk.RotaryLimitJoint(self.l_door_body, space.static_body, -self.rotation - math.pi / 2.0, -self.rotation) space.add(j2)
def testRestAngle(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.DampedRotarySpring(a, b, 1, 0, 0) self.assertEqual(j.rest_angle, 1) j.rest_angle = 2 self.assertEqual(j.rest_angle, 2)
def testStiffness(self): a, b = p.Body(10, 10), p.Body(20, 20) j = p.DampedRotarySpring(a, b, 0, 1, 0) self.assertEqual(j.stiffness, 1) j.stiffness = 2 self.assertEqual(j.stiffness, 2)
def build(space, group): scale = 2 normal_rect = pygame.Rect(0, 0, 32 * scale, 40 * scale) model = CatModel() sprites = list() pymunk_objects = list() seat_surface = resources.gfx("seat.png", convert_alpha=True) feet_surface = resources.gfx("wheel.png", convert_alpha=True) filter1 = pymunk.ShapeFilter(group=0b000001) filter2 = pymunk.ShapeFilter(group=0b000010) # Main body body_body = pymunk.Body(0.00001, pymunk.inf) body_body.position = normal_rect.topleft model.main_body = body_body pymunk_objects.append(body_body) # seat seat_body = pymunk.Body() seat_body.center_of_gravity = normal_rect.midbottom seat_body.position = normal_rect.topleft seat_shape = make_hitbox(seat_body, normal_rect) seat_shape.mass = .5 seat_shape.elasticity = 0 seat_shape.friction = 2 seat_shape.filter = filter1 seat_sprite = ShapeSprite(seat_surface, seat_shape) seat_sprite._layer = 1 sprites.append(seat_sprite) pymunk_objects.append(seat_body) pymunk_objects.append(seat_shape) # build feet radius = normal_rect.width * .55 feet_body = pymunk.Body() model.feet = feet_body feet_shape = pymunk.Circle(feet_body, radius, (0, 0)) feet_shape.mass = 1 feet_shape.elasticity = 0 feet_shape.friction = 100 feet_shape.filter = filter1 feet_sprite = ShapeSprite(feet_surface, feet_shape) feet_sprite._layer = 0 sprites.append(feet_sprite) pymunk_objects.append(feet_body) pymunk_objects.append(feet_shape) # adjust the position of the feet and body feet_body.position = normal_rect.midbottom # motor and joints for feet motor = pymunk.SimpleMotor(body_body, feet_body, 0.0) model.motor = motor pymunk_objects.append(motor) x, y = normal_rect.midbottom y -= 10 joint = pymunk.PivotJoint(body_body, feet_body, (x, y), (0, 0)) pymunk_objects.append(joint) joint = pymunk.PivotJoint(seat_body, feet_body, (x, y), (0, 0)) pymunk_objects.append(joint) # cat cat_surface = resources.gfx("cat.png", convert_alpha=True) cat_rect = pygame.Rect(0, 0, 64, 48) cat_body = pymunk.Body() cat_shape = make_hitbox(cat_body, cat_rect) cat_body.position = normal_rect.x, normal_rect.y - cat_rect.height - 10 cat_shape.mass = 0.001 cat_shape.elasticity = .1 cat_shape.friction = 10.0 cat_shape.filter = filter2 cat_sprite = ShapeSprite(cat_surface, cat_shape, 1.5) cat_sprite._layer = 2 sprites.append(cat_sprite) pymunk_objects.append(cat_body) pymunk_objects.append(cat_shape) # hold cat the the seat spring = pymunk.DampedSpring(seat_body, cat_body, normal_rect.midtop, cat_rect.midbottom, 0, 1, 0) pymunk_objects.append(spring) # tilt corrector spring = pymunk.DampedRotarySpring(body_body, seat_body, radians(0), 60000, 20000) spring.collide_bodies = False pymunk_objects.append(spring) model.sprites = sprites model.pymunk_objects = pymunk_objects space.add(pymunk_objects) group.add(*sprites) return model
def main(): # Primatians - woo print "Running Python version:", sys.version print "Running PyGame version:", pygame.ver print "Running PyMunk version:", pymunk.version print "Running Primatians version:", __version__ pygame.init() screen = pygame.display.set_mode((800, 500), pygame.RESIZABLE) bg, bg_rect = background_image('rainforest.jpg') screen.blit(bg, (0, 0)) pygame.display.set_caption("Primatians - A Nanho Games Production") clock = pygame.time.Clock() running = True # Physics stuff space = pymunk.Space(50) space.gravity = (90, -90.0) # Balls balls = [] mass = 1 radius = 25 inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0)) body = pymunk.Body(mass, inertia) x = random.randint(0, 500) body.position = 400, 400 shape = pymunk.Circle(body, radius, (0, 0)) shape.elasticity = 0.95 space.add(body, shape) balls.append(shape) # Primates primates = [] mass = 1 radius = 25 inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0)) body = pymunk.Body(mass, inertia) x = random.randint(0, 500) body.position = 10, 10 shape = pymunk.Circle(body, radius, (0, 0)) shape.elasticity = 0.95 space.add(body, shape) primates.append(shape) # Walls first static_body = pymunk.Body() # x1,y1, x2,y2 static_lines = [pymunk.Segment(static_body, (0.0, 0.0), (0.0, 500.0), 5.0), pymunk.Segment(static_body, (0.0, 500.0), (800.0, 500.0), 5.0), pymunk.Segment(static_body, (800.0, 500.0), (800.0, 0.0), 5.0), pymunk.Segment(static_body, (800.0, 0.0), (0.0, 0.0), 5.0) ] for line in static_lines: line.elasticity = 0.7 line.group = 1 space.add(static_lines) # Some Logs static_logs = [pymunk.Segment(static_body, (200, 250), (600, 250), 5)] for logs in static_logs: logs.elasticity = 1 logs.group = 1 space.add(static_logs) # Add Flippers ( handler tree logs) fp = [(20, -20), (-120, 0), (20, 20)] mass = 100 moment = pymunk.moment_for_poly(mass, fp) # right flipper r_flipper_body = pymunk.Body(mass, moment) r_flipper_body.position = 750, 10 r_flipper_shape = pymunk.Poly(r_flipper_body, fp) space.add(r_flipper_body, r_flipper_shape) r_flipper_joint_body = pymunk.Body() r_flipper_joint_body.position = r_flipper_body.position j = pymunk.PinJoint(r_flipper_body, r_flipper_joint_body, (0, 0), (0, 0)) #todo: tweak values of spring better s = pymunk.DampedRotarySpring(r_flipper_body, r_flipper_joint_body, 0.15, 20000000, 900000) space.add(j, s) # left flipper l_flipper_body = pymunk.Body(mass, moment) l_flipper_body.position = 10, 10 l_flipper_shape = pymunk.Poly(l_flipper_body, [(-x, y) for x, y in fp]) space.add(l_flipper_body, l_flipper_shape) l_flipper_joint_body = pymunk.Body() l_flipper_joint_body.position = l_flipper_body.position j = pymunk.PinJoint(l_flipper_body, l_flipper_joint_body, (0, 0), (0, 0)) s = pymunk.DampedRotarySpring(l_flipper_body, l_flipper_joint_body, -0.15, 20000000, 900000) space.add(j, s) r_flipper_shape.group = l_flipper_shape.group = 1 r_flipper_shape.elasticity = l_flipper_shape.elasticity = 0.4 # sprites ball_sprite = GameSprite('banana-small.png') primate1_sprite = GameSprite('primate2.png') #ball_sprite = pygame.image.load('assets/banana-small.png') #primate1_sprite = pygame.image.load('assets/primate2.png') while running: for event in pygame.event.get(): if event.type == QUIT: running = False elif event.type == KEYDOWN and event.key == K_ESCAPE: running = False elif event.type == KEYDOWN and event.key == K_z: l_flipper_body.apply_impulse(Vec2d.unit() * -40000, (-100, 0)) elif event.type == KEYDOWN and event.key == K_x: r_flipper_body.apply_impulse(Vec2d.unit() * 40000, (-100, 0)) # Draw # backgroundLayer.draw() #screen.fill(THECOLORS["darkolivegreen"]) screen.blit(bg, (0, 0)) # Draw lines for line in static_lines: body = line.body pv1 = body.position + line.a.rotated(body.angle) pv2 = body.position + line.b.rotated(body.angle) p1 = to_pygame(pv1) p2 = to_pygame(pv2) pygame.draw.lines(screen, THECOLORS["black"], False, [p1, p2]) # Draw logs for log in static_logs: body = log.body pv1 = body.position + log.a.rotated(body.angle) pv2 = body.position + log.b.rotated(body.angle) p1 = to_pygame(pv1) p2 = to_pygame(pv2) pygame.draw.lines(screen, THECOLORS["brown"], False, [p1,p2]) for ball in balls: p = to_pygame(ball.body.position) #angle_degrees = math.degrees(ball.body.angle) + 180 #rotated_logo_img = pygame.transform.rotate(ball_sprite, angle_degrees) #offset = Vec2d(rotated_logo_img.get_size()) / 2. #x, y = ball.get_points()[0] #p = Vec2d(x,y) #p = p - offset screen.blit(ball_sprite.image, p) ball_sprite.rect.center = p pygame.draw.circle(screen, THECOLORS["yellow"], p, int(ball.radius), 2) for primate in primates: p = to_pygame(primate.body.position) screen.blit(primate1_sprite.image, p) primate1_sprite.rect.center = p r_flipper_body.position = 790, 10 l_flipper_body.position = 10, 10 r_flipper_body.velocity = l_flipper_body.velocity = 0,0 for f in [r_flipper_shape, l_flipper_shape]: ps = f.get_points() ps.append(ps[0]) ps = map(to_pygame, ps) color = THECOLORS["burlywood4"] # we need to rotate 180 degrees because of the y coordinate flip # angle_degrees = math.degrees(f.body.angle) + 180 # rotated_logo_img = pygame.transform.rotate(log_sprite, angle_degrees) # offset = Vec2d(rotated_logo_img.get_size()) / 2. # x, y = f.get_points()[0] # p = Vec2d(x,y) # p = p - offset # screen.blit(log_sprite, p) #pygame.draw.lines(screen, color, False, ps) pygame.draw.polygon(screen, color, ps, 0) #if pygame.sprite.spritecollide(primate1_sprite, [ball_sprite], 1): if pygame.sprite.collide_rect(primate1_sprite, ball_sprite): print primate1_sprite.rect print ball_sprite.rect print 'Sprites Collide' # Update physics dt = 1.0/60.0/5 for x in range(5): space.step(dt) pygame.display.flip() clock.tick(50)
def main(): # Primatians - woo print "Running Python version:", sys.version print "Running PyGame version:", pygame.ver print "Running PyMunk version:", pymunk.version print "Running Primatians version:", __version__ pygame.init() screen = pygame.display.set_mode((800, 500), pygame.RESIZABLE) pygame.display.set_caption("Primatians - A Nanho Games Production") # make our background object colorBackground = Color("darkolivegreen4") backgroundLayer = DrawSurf(screen, colorBackground) clock = pygame.time.Clock() running = True # Physics stuff space = pymunk.Space(50) space.gravity = (90, -90.0) # Balls balls = [] mass = 1 radius = 25 inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0)) body = pymunk.Body(mass, inertia) x = random.randint(0, 500) body.position = 400, 400 shape = pymunk.Circle(body, radius, (0, 0)) shape.elasticity = 0.95 space.add(body, shape) balls.append(shape) # Walls first static_body = pymunk.Body() # x1,y1, x2,y2 static_lines = [ pymunk.Segment(static_body, (0.0, 0.0), (0.0, 500.0), 5.0), pymunk.Segment(static_body, (0.0, 500.0), (800.0, 500.0), 5.0), pymunk.Segment(static_body, (800.0, 500.0), (800.0, 0.0), 5.0), pymunk.Segment(static_body, (800.0, 0.0), (0.0, 0.0), 5.0) ] for line in static_lines: line.elasticity = 0.7 line.group = 1 space.add(static_lines) # Some Logs static_logs = [pymunk.Segment(static_body, (200, 250), (600, 250), 5)] for logs in static_logs: logs.elasticity = 1 logs.group = 1 space.add(static_logs) # Add Flippers ( handler tree logs) fp = [(20, -20), (-120, 0), (20, 20)] mass = 100 moment = pymunk.moment_for_poly(mass, fp) # right flipper r_flipper_body = pymunk.Body(mass, moment) r_flipper_body.position = 750, 10 r_flipper_shape = pymunk.Poly(r_flipper_body, fp) space.add(r_flipper_body, r_flipper_shape) r_flipper_joint_body = pymunk.Body() r_flipper_joint_body.position = r_flipper_body.position j = pymunk.PinJoint(r_flipper_body, r_flipper_joint_body, (0, 0), (0, 0)) #todo: tweak values of spring better s = pymunk.DampedRotarySpring(r_flipper_body, r_flipper_joint_body, 0.15, 20000000, 900000) space.add(j, s) # left flipper l_flipper_body = pymunk.Body(mass, moment) l_flipper_body.position = 10, 10 l_flipper_shape = pymunk.Poly(l_flipper_body, [(-x, y) for x, y in fp]) space.add(l_flipper_body, l_flipper_shape) l_flipper_joint_body = pymunk.Body() l_flipper_joint_body.position = l_flipper_body.position j = pymunk.PinJoint(l_flipper_body, l_flipper_joint_body, (0, 0), (0, 0)) s = pymunk.DampedRotarySpring(l_flipper_body, l_flipper_joint_body, -0.15, 20000000, 900000) space.add(j, s) # new flippers fp = [(20, -20), (-120, 0), (20, 20)] #fp = [(120, 0), (120,-20),(-120,0)] mass = 100 moment = pymunk.moment_for_poly(mass, fp) # top-right flipper tr_flipper_body = pymunk.Body(mass, moment) tr_flipper_body.position = 750, 450 tr_flipper_shape = pymunk.Poly(tr_flipper_body, fp) space.add(tr_flipper_body, tr_flipper_shape) tr_flipper_joint_body = pymunk.Body() tr_flipper_joint_body.position = tr_flipper_body.position j = pymunk.PinJoint(tr_flipper_body, tr_flipper_joint_body, (0, 0), (0, 0)) #todo: tweak values of spring better s = pymunk.DampedRotarySpring(tr_flipper_body, tr_flipper_joint_body, 0.15, 20000000, 900000) space.add(j, s) # top-left flipper tl_flipper_body = pymunk.Body(mass, moment) tl_flipper_body.position = 50, 850 tl_flipper_shape = pymunk.Poly(tl_flipper_body, [(-x, y) for x, y in fp]) space.add(tl_flipper_body, tl_flipper_shape) tl_flipper_joint_body = pymunk.Body() tl_flipper_joint_body.position = tl_flipper_body.position j = pymunk.PinJoint(tl_flipper_body, tl_flipper_joint_body, (0, 0), (0, 0)) s = pymunk.DampedRotarySpring(tl_flipper_body, tl_flipper_joint_body, -0.15, 20000000, 900000) space.add(j, s) r_flipper_shape.group = l_flipper_shape.group = tr_flipper_shape.group = tl_flipper_shape.group = 1 r_flipper_shape.elasticity = l_flipper_shape.elasticity = tr_flipper_shape.elasticity = tl_flipper_shape.elasticity = 0.4 while running: for event in pygame.event.get(): if event.type == QUIT: running = False elif event.type == KEYDOWN and event.key == K_ESCAPE: running = False elif event.type == KEYDOWN and event.key == K_j: r_flipper_body.apply_impulse(Vec2d.unit() * 40000, (-100, 0)) elif event.type == KEYDOWN and event.key == K_f: l_flipper_body.apply_impulse(Vec2d.unit() * -40000, (-100, 0)) elif event.type == KEYDOWN and event.key == K_g: tl_flipper_body.apply_impulse(Vec2d.unit() * 40000, (-100, 0)) elif event.type == KEYDOWN and event.key == K_h: tr_flipper_body.apply_impulse(Vec2d.unit() * -40000, (-100, 0)) if event.type == pygame.VIDEORESIZE: screen_size = event.size screen = pygame.display.set_mode(screen_size, pygame.RESIZABLE) oldBg = backgroundLayer.surface.copy() backgroundLayer = DrawSurf(screen, backgroundLayer.color) backgroundLayer.surface.blit(oldBg, (0, 0)) # Draw # backgroundLayer.draw() screen.fill(THECOLORS["darkolivegreen"]) # Draw lines for line in static_lines: body = line.body pv1 = body.position + line.a.rotated(body.angle) pv2 = body.position + line.b.rotated(body.angle) p1 = to_pygame(pv1) p2 = to_pygame(pv2) pygame.draw.lines(screen, THECOLORS["black"], False, [p1, p2]) # Draw logs for log in static_logs: body = log.body pv1 = body.position + log.a.rotated(body.angle) pv2 = body.position + log.b.rotated(body.angle) p1 = to_pygame(pv1) p2 = to_pygame(pv2) pygame.draw.lines(screen, THECOLORS["brown"], False, [p1, p2]) for ball in balls: p = to_pygame(ball.body.position) pygame.draw.circle(screen, THECOLORS["yellow"], p, int(ball.radius), 2) r_flipper_body.position = 790, 10 l_flipper_body.position = 10, 10 tr_flipper_body.position = 790, 490 tl_flipper_body.position = 10, 490 r_flipper_body.velocity = l_flipper_body.velocity = tr_flipper_body.velocity = tl_flipper_body.velocity = 0, 0 for f in [ r_flipper_shape, l_flipper_shape, tr_flipper_shape, tl_flipper_shape, ]: ps = f.get_points() ps.append(ps[0]) ps = map(to_pygame, ps) color = THECOLORS["red"] pygame.draw.lines(screen, color, False, ps) # Update physics dt = 1.0 / 60.0 / 5 for x in range(5): space.step(dt) pygame.display.flip() clock.tick(50)
def __init__(self, b, b2, angle, stiffness, damping): joint = pymunk.DampedRotarySpring(b, b2, angle, stiffness, damping) space.add(joint)
def run(): pygame.init() pygame.display.set_caption("Pinball Simulator") screen = pygame.display.set_mode((600, 600)) clock = pygame.time.Clock() running = True ### Physics stuff space = pymunk.Space() space.gravity = (0.0, -900.0) draw_options = pymunk.pygame_util.DrawOptions(screen) ## Balls balls = [] ### walls static_lines = [ pymunk.Segment(space.static_body, (150, 100.0), (50.0, 550.0), 1.0), pymunk.Segment(space.static_body, (450.0, 100.0), (550.0, 550.0), 1.0), pymunk.Segment(space.static_body, (50.0, 550.0), (300.0, 600.0), 1.0), pymunk.Segment(space.static_body, (300.0, 600.0), (550.0, 550.0), 1.0), pymunk.Segment(space.static_body, (300.0, 420.0), (400.0, 400.0), 1.0) ] for line in static_lines: line.elasticity = 0.7 line.group = 1 space.add(static_lines) fp = [(20, -20), (-120, 0), (20, 20)] mass = 100 moment = pymunk.moment_for_poly(mass, fp) # right flipper r_flipper_body = pymunk.Body(mass, moment) r_flipper_body.position = 450, 100 r_flipper_shape = pymunk.Poly(r_flipper_body, fp) space.add(r_flipper_body, r_flipper_shape) r_flipper_joint_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) r_flipper_joint_body.position = r_flipper_body.position j = pymunk.PinJoint(r_flipper_body, r_flipper_joint_body, (0, 0), (0, 0)) # todo: tweak values of spring better s = pymunk.DampedRotarySpring(r_flipper_body, r_flipper_joint_body, 0.15, 20000000, 900000) space.add(j, s) # left flipper l_flipper_body = pymunk.Body(mass, moment) l_flipper_body.position = 150, 100 l_flipper_shape = pymunk.Poly(l_flipper_body, [(-x, y) for x, y in fp]) space.add(l_flipper_body, l_flipper_shape) l_flipper_joint_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) l_flipper_joint_body.position = l_flipper_body.position j = pymunk.PinJoint(l_flipper_body, l_flipper_joint_body, (0, 0), (0, 0)) s = pymunk.DampedRotarySpring(l_flipper_body, l_flipper_joint_body, -0.15, 20000000, 900000) space.add(j, s) r_flipper_shape.group = l_flipper_shape.group = 1 r_flipper_shape.elasticity = l_flipper_shape.elasticity = 0.4 # "bumpers" for p in [(240, 500), (360, 500)]: body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) body.position = p shape = pymunk.Circle(body, 10) shape.elasticity = 1.5 space.add(shape) while running: for event in pygame.event.get(): if event.type == QUIT: running = False pygame.quit() elif event.type == KEYDOWN and event.key == K_ESCAPE: running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "flipper.png") elif event.type == KEYDOWN and event.key == K_d: r_flipper_body.apply_impulse_at_local_point( Vec2d.unit() * 40000, (-100, 0)) elif event.type == KEYDOWN and event.key == K_a: l_flipper_body.apply_impulse_at_local_point( Vec2d.unit() * -40000, (-100, 0)) elif event.type == KEYDOWN and event.key == K_s: mass = 1 radius = 25 inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0)) body = pymunk.Body(mass, inertia) x = random.randint(115, 350) body.position = x, 400 shape = pymunk.Circle(body, radius, (0, 0)) shape.elasticity = 0.95 space.add(body, shape) balls.append(shape) ### Clear screen screen.fill(THECOLORS["white"]) ### Draw stuff space.debug_draw(draw_options) r_flipper_body.position = 450, 100 l_flipper_body.position = 150, 100 r_flipper_body.velocity = l_flipper_body.velocity = 0, 0 ### Remove any balls outside to_remove = [] for ball in balls: if ball.body.position.get_distance((300, 300)) > 1000: to_remove.append(ball) for ball in to_remove: space.remove(ball.body, ball) balls.remove(ball) ### Update physics dt = 1.0 / 60.0 / 5. for x in range(5): space.step(dt) draw_helptext(screen) ### Flip screen pygame.display.flip() clock.tick(50)
box_offset = box_size * 4, 0 b1 = add_ball(space, (50, 60), box_offset) b2 = add_ball(space, (150, 60), box_offset) c = pymunk.DampedSpring(b1, b2, (30, 0), (-30, 0), 20, 5, 0.3) txts[box_offset] = inspect.getdoc(c) space.add(c) box_offset = box_size * 5, 0 b1 = add_bar(space, (50, 80), box_offset) b2 = add_bar(space, (150, 80), box_offset) # Add some joints to hold the circles in place. space.add( pymunk.PivotJoint(b1, space.static_body, (50, 80) + Vec2d(box_offset))) space.add( pymunk.PivotJoint(b2, space.static_body, (150, 80) + Vec2d(box_offset))) c = pymunk.DampedRotarySpring(b1, b2, 0, 3000, 60) txts[box_offset] = inspect.getdoc(c) space.add(c) box_offset = 0, box_size b1 = add_lever(space, (50, 100), box_offset) b2 = add_lever(space, (150, 100), box_offset) # Add some joints to hold the circles in place. space.add( pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(box_offset))) space.add( pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(box_offset))) # Hold their rotation within 90 degrees of each other. c = pymunk.RotaryLimitJoint(b1, b2, math.pi / 2, math.pi / 2) txts[box_offset] = inspect.getdoc(c) space.add(c)
def setup(self, *args, **kwargs): super().setup(*args, **kwargs) # physics setup, starting with main body # signature: moment_for_circle(mass, inner_rad, outer_rad, offset) inertia = pm.moment_for_circle(self.mass, 0, self.radius, (0, 0)) self.robot_body = body = pm.Body(self.mass, inertia) body.position = self.init_pos body.angle = self.init_angle self.add_to_space(body) # For control. The rough joint setup was taken form tank.py in the # pymunk examples. self.control_body = control_body = pm.Body(body_type=pm.Body.KINEMATIC) control_body.position = self.init_pos control_body.angle = self.init_angle self.add_to_space(control_body) pos_control_joint = pm.PivotJoint(control_body, body, (0, 0), (0, 0)) pos_control_joint.max_bias = 0 pos_control_joint.max_force = self.phys_vars.robot_pos_joint_max_force self.add_to_space(pos_control_joint) rot_control_joint = pm.GearJoint(control_body, body, 0.0, 1.0) rot_control_joint.error_bias = 0.0 rot_control_joint.max_bias = 2.5 rot_control_joint.max_force = self.phys_vars.robot_rot_joint_max_force self.add_to_space(rot_control_joint) # googly eye control bodies & joints self.pupil_bodies = [] for eye_side in [-1, 1]: eye_mass = self.mass / 10 eye_radius = self.radius eye_inertia = pm.moment_for_circle(eye_mass, 0, eye_radius, (0, 0)) eye_body = pm.Body(eye_mass, eye_inertia) eye_body.angle = self.init_angle eye_joint = pm.DampedRotarySpring(body, eye_body, 0, 0.1, 3e-3) eye_joint.max_bias = 3.0 eye_joint.max_force = 0.001 self.pupil_bodies.append(eye_body) self.add_to_space(eye_body, eye_joint) # finger bodies/controls (annoying) finger_thickness = 0.25 * self.radius finger_upper_length = 1.1 * self.radius finger_lower_length = 0.7 * self.radius self.finger_bodies = [] self.finger_motors = [] finger_vertices = [] finger_inner_vertices = [] self.target_finger_angle = 0.0 for finger_side in [-1, 1]: # basic finger body finger_verts = make_finger_vertices( upper_arm_len=finger_upper_length, forearm_len=finger_lower_length, thickness=finger_thickness, side_sign=finger_side) finger_vertices.append(finger_verts) finger_inner_verts = make_finger_vertices( upper_arm_len=finger_upper_length - ROBOT_LINE_THICKNESS * 2, forearm_len=finger_lower_length - ROBOT_LINE_THICKNESS * 2, thickness=finger_thickness - ROBOT_LINE_THICKNESS * 2, side_sign=finger_side) finger_inner_verts = [[(x, y + ROBOT_LINE_THICKNESS) for x, y in box] for box in finger_inner_verts] finger_inner_vertices.append(finger_inner_verts) # these are movement limits; they are useful below, but also # necessary to make initial positioning work if finger_side < 0: lower_rot_lim = -self.finger_rot_limit_inner upper_rot_lim = self.finger_rot_limit_outer if finger_side > 0: lower_rot_lim = -self.finger_rot_limit_outer upper_rot_lim = self.finger_rot_limit_inner finger_mass = self.mass / 8 finger_inertia = pm.moment_for_poly(finger_mass, sum(finger_verts, [])) finger_body = pm.Body(finger_mass, finger_inertia) if finger_side < 0: delta_finger_angle = upper_rot_lim finger_body.angle = self.init_angle + delta_finger_angle else: delta_finger_angle = lower_rot_lim finger_body.angle = self.init_angle + delta_finger_angle # position of finger relative to body finger_rel_pos = (finger_side * self.radius * 0.45, self.radius * 0.1) finger_rel_pos_rot = gtools.rotate_vec(finger_rel_pos, self.init_angle) finger_body.position = gtools.add_vecs(body.position, finger_rel_pos_rot) self.add_to_space(finger_body) self.finger_bodies.append(finger_body) # pin joint to keep it in place (it will rotate around this point) finger_pin = pm.PinJoint( body, finger_body, finger_rel_pos, (0, 0), ) finger_pin.error_bias = 0.0 self.add_to_space(finger_pin) # rotary limit joint to stop it from getting too far out of line finger_limit = pm.RotaryLimitJoint(body, finger_body, lower_rot_lim, upper_rot_lim) finger_limit.error_bias = 0.0 self.add_to_space(finger_limit) # motor to move the fingers around (very limited in power so as not # to conflict with rotary limit joint) finger_motor = pm.SimpleMotor(body, finger_body, 0.0) finger_motor.rate = 0.0 finger_motor.max_bias = 0.0 finger_motor.max_force = self.phys_vars.robot_finger_max_force self.add_to_space(finger_motor) self.finger_motors.append(finger_motor) # For collision. Main body circle. Signature: Circle(body, radius, # offset). robot_group = 1 body_shape = pm.Circle(body, self.radius, (0, 0)) body_shape.filter = pm.ShapeFilter(group=robot_group) body_shape.friction = 0.5 self.add_to_space(body_shape) # the fingers finger_shapes = [] for finger_body, finger_verts, finger_side in zip( self.finger_bodies, finger_vertices, [-1, 1]): finger_subshapes = [] for finger_subverts in finger_verts: finger_subshape = pm.Poly(finger_body, finger_subverts) finger_subshape.filter = pm.ShapeFilter(group=robot_group) # grippy fingers finger_subshape.friction = 5.0 finger_subshapes.append(finger_subshape) self.add_to_space(*finger_subshapes) finger_shapes.append(finger_subshapes) # graphics setup # draw a circular body circ_body_in = r.make_circle(radius=self.radius - ROBOT_LINE_THICKNESS, res=100) circ_body_out = r.make_circle(radius=self.radius, res=100) robot_colour = COLOURS_RGB['grey'] dark_robot_colour = darken_rgb(robot_colour) light_robot_colour = lighten_rgb(robot_colour, 4) circ_body_in.set_color(*robot_colour) circ_body_out.set_color(*dark_robot_colour) # draw the two fingers self.finger_xforms = [] finger_outer_geoms = [] finger_inner_geoms = [] for finger_outer_subshapes, finger_inner_verts, finger_side in zip( finger_shapes, finger_inner_vertices, [-1, 1]): finger_xform = r.Transform() self.finger_xforms.append(finger_xform) for finger_subshape in finger_outer_subshapes: vertices = [(v.x, v.y) for v in finger_subshape.get_vertices()] finger_outer_geom = r.make_polygon(vertices) finger_outer_geom.set_color(*robot_colour) finger_outer_geom.add_attr(finger_xform) finger_outer_geoms.append(finger_outer_geom) for vertices in finger_inner_verts: finger_inner_geom = r.make_polygon(vertices) finger_inner_geom.set_color(*light_robot_colour) finger_inner_geom.add_attr(finger_xform) finger_inner_geoms.append(finger_inner_geom) for geom in finger_outer_geoms: self.viewer.add_geom(geom) for geom in finger_inner_geoms: self.viewer.add_geom(geom) # draw some cute eyes eye_shapes = [] self.pupil_transforms = [] for x_sign in [-1, 1]: eye = r.make_circle(radius=0.2 * self.radius, res=20) eye.set_color(1.0, 1.0, 1.0) eye_base_transform = r.Transform().set_translation( x_sign * 0.4 * self.radius, 0.3 * self.radius) eye.add_attr(eye_base_transform) pupil = r.make_circle(radius=0.12 * self.radius, res=10) pupil.set_color(0.1, 0.1, 0.1) # The pupils point forward slightly pupil_transform = r.Transform() pupil.add_attr(r.Transform().set_translation( 0, self.radius * 0.07)) pupil.add_attr(pupil_transform) pupil.add_attr(eye_base_transform) self.pupil_transforms.append(pupil_transform) eye_shapes.extend([eye, pupil]) # join them together self.robot_xform = r.Transform() robot_compound = r.Compound([circ_body_out, circ_body_in, *eye_shapes]) robot_compound.add_attr(self.robot_xform) self.viewer.add_geom(robot_compound)