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 PinJoint
s.
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 RotaryLimitJoint
s, but apparently they don't work