As a first project, I started working on a ragdoll animation framework. The idea is that a Ragdoll (perhaps better called a RagdollPart) is a Sprite that has other Ragdoll parts attached to it through a system of Plugs and Sockets.
A Ragdoll has 0 or more Sockets, and exactly one Plug. The location of the Plug and Sockets are defined by the angle and distance (a Vector) from the center of their Ragdoll. A Socket also has a twist property that affects the rotation of the attached Plug, rotating the Plug about the Socket. (or is the other way around, I forgot aleady!
)
Ragdoll's plug is attached to another Ragdoll's Socket using it's Ragdoll.connect method, such as "LeftArm.connect( Body, "RightShoulder" )
A Ragdoll has a ".snap" method that causes it's attacked RagDolls to snap their Plugs to the correct socket. These Ragdolls, then call their .snap method, effectively updating the entire Ragdoll collective's location and angles.
I am note sure my design is correct. But I think it looks pretty good.
Here's the methods in action.
parts = {}// "head": null, "torso":null, "left":null, "right": null}
parts.torso = new Ragdoll
parts.torso.image = circleshape
parts.torso.tint = color.blue
parts.torso.moveto gfx.width / 2, gfx.height / 2
parts.torso.scale = [ 1,1 ]
parts.torso.addSocket( "neck", 0, 1)
parts.torso.addSocket( "right", 90, 1)
parts.torso.addSocket( "left", 270, 1)
parts.torso.sockets.left.twist = -45
parts.torso.sockets.right.twist = function; return 45 + 90* sin(time*360/90);end function
print "torso done"
parts.head = new Ragdoll
parts.head.image = circleshape
parts.head.scale = [.75,.5]
parts.head.addPlug("neck",180,1)
parts.head.connect(parts.torso)
print "head done"
parts.left = new Ragdoll
parts.left.image = circleshape
parts.left.tint = color.green
parts.left.scale = [ .2,2 ]
parts.left.addPlug("shoulder", 0,.8)
parts.left.connect(parts.torso, "left")
parts.right = new Ragdoll
parts.right.image = circleshape
parts.right.tint = color.green
parts.right.scale = [ .2,2 ]
parts.right.addPlug("shoulder", 0,.8)
parts.right.connect(parts.torso, "right")
print "Press x to stop animation."
t = time
while not key.pressed("x")
parts.torso.scale = [2, .1 + abs(sin(time360/180pi/10)) * 1.9 ]
parts.torso.rotation += ((time - t) * 360 / 5)
t = time
parts.torso.snapall
yield
end while