예제 #1
0
    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)
예제 #2
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)
예제 #3
0
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
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
 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)
예제 #7
0
    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
예제 #9
0
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
예제 #10
0
 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
예제 #11
0
 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)
예제 #12
0
    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"
예제 #13
0
    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)
예제 #14
0
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
예제 #15
0
파일: main.py 프로젝트: ExXidad/Paper
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
예제 #16
0
 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)
예제 #17
0
#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
예제 #18
0
파일: flipper.py 프로젝트: yurokji/pymunk
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)
예제 #19
0
    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
예제 #20
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)
예제 #21
0
    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)
예제 #22
0
 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)
예제 #23
0
 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)
예제 #24
0
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
예제 #25
0
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)
예제 #26
0
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)
예제 #27
0
 def __init__(self, b, b2, angle, stiffness, damping):
     joint = pymunk.DampedRotarySpring(b, b2, angle, stiffness, damping)
     space.add(joint)
예제 #28
0
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)
예제 #29
0
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)
예제 #30
0
    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)