0

I'm writing a script in pymunk/pygame to create a character for a game. At this point, I have a ragdoll (the skeleton) with body parts linked by PinJoints.

The problem is that in this way I don't have an active ragdoll, but only a dead stickman that falls like butter on the ground. How can I make it standing and, eventually, make procedural animations on it, like walking or climbing or grabbing objects?

This is the code to define the ragdoll (sorry if it's not so 'pythonic'


class BonePoint():
    def __init__(self, x, y, group):
        self.body = pymunk.Body()
        self.body.position = x, y
        self.shape = pymunk.Circle(self.body, radius=10)
        self.shape.elasticity = 0.5
        self.shape.density = 1
        self.shape.filter = pymunk.ShapeFilter(group = group)
        space.add(self.shape, self.body)
    
    def draw(self):
        x, y = self.body.position
        pygame.draw.circle(screen, (255,0,0), (int(x), int(y)), 10)


class Bone():
    def __init__(self, body1, attachement, min, max, identifier = "body"):
        self.body1 = body1
        if identifier == "body":
            self.body2 = attachement
        elif identifier == "position":
            self.body2 = pymunk.Body(body_type=pymunk.Body.STATIC)
            self.body2.position = attachement
        joint = pymunk.PinJoint(self.body1, self.body2)
        space.add(joint)
    def draw(self):
        pos1 = self.body1.position
        pos2 = self.body2.position
        pygame.draw.line(screen, (0,0,0), pos1, pos2, 10)

class Player():
    def __init__(self, x, y):
        self.shoulders = BonePoint(x, y, 1)
        self.head = BonePoint(x, y-40, 1)
        self.left_elbow = BonePoint(x-50, y, 1)
        self.left_hand = BonePoint(x-100, y, 1)
        self.right_elbow = BonePoint(x+50, y, 1)
        self.right_hand = BonePoint(x+100, y, 1)
        self.hip = BonePoint(x, y+100, 1)
        self.left_knee = BonePoint(x, y+150, 1)
        self.right_knee = BonePoint(x, y+150, 1)
        self.left_foot = BonePoint(x, y+200, 1)
        self.right_foot = BonePoint(x, y+200, 1)
        
        self.neck_bone = Bone(self.shoulders.body, self.head.body, -pi/4, pi/4)
        self.left_arm_bone = Bone(self.shoulders.body, self.left_elbow.body, -pi/2, pi/2)
        self.left_forearm_bone = Bone(self.left_elbow.body, self.left_hand.body, 0, pi)
        self.right_arm_bone = Bone(self.shoulders.body, self.right_elbow.body, -pi/2, pi/2)
        self.right_forearm_bone = Bone(self.right_elbow.body, self.right_hand.body, 0, pi)
        self.left_thigh_bone = Bone(self.hip.body, self.left_knee.body, -pi/4, pi/1.5)
        self.left_leg_bone = Bone(self.left_knee.body, self.left_foot.body, -pi/1.5, 0)
        self.right_thigh_bone = Bone(self.hip.body, self.right_knee.body, -pi/4, pi/1.5)
        self.right_leg_bone = Bone(self.right_knee.body, self.right_foot.body, -pi/1.5, 0)
        self.torso_bone = Bone(self.shoulders.body, self.hip.body, -pi/2, pi/2)
        
        
    def draw_player(self):
        self.shoulders.draw()
        self.head.draw()
        self.left_elbow.draw()
        self.left_hand.draw()
        self.right_elbow.draw()
        self.right_hand.draw()
        self.hip.draw()
        self.left_knee.draw()
        self.right_knee.draw()
        self.left_foot.draw()
        self.right_foot.draw()
        
        self.neck_bone.draw()
        self.left_arm_bone.draw()
        self.left_forearm_bone.draw()
        self.right_arm_bone.draw()
        self.right_forearm_bone.draw()
        self.torso_bone.draw()
        self.left_thigh_bone.draw()
        self.left_leg_bone.draw()
        self.right_thigh_bone.draw()
        self.right_leg_bone.draw()

Ps. I tried using RotaryLimitJoints, but apparently they don't work

  • You could also try to ask at https://gamedev.stackexchange.com/ I think the main problem is not specific to pymunk, you would do the same with Box2D or other physics engines. – viblo May 19 '23 at 20:02

1 Answers1

0

The easiest is the classic death ragdoll, that happens when the player can not control the character anymore.

In those cases, what you do is you animate the character "normally" while the player is in control and move the physics bodies accordingly to match. Then when the player lose control (i.e. character death), you let the physics bodies "free".

viblo
  • 4,159
  • 4
  • 20
  • 28