Ragdoll Physics using Verlet Integration
Ragdoll Physics using Verlet Integration
based on Keith Peters's "AdvancED AS3.0 Animation"
/**
* Copyright aizoaikawa ( http://wonderfl.net/user/aizoaikawa )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1TXD
*/
// Ragdoll Physics using Verlet Integration
// based on Keith Peters's "AdvancED AS3.0 Animation"
package {
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.ui.Keyboard;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.geom.Rectangle;
import flash.display.Sprite;
import flash.events.Event;
public class RagDoll extends Sprite {
private var rect_:Rectangle;
private var pts_:Vector.<VP>;
private var sticks_:Vector.<VS>;
private var springs_:Vector.<VS>;
private var kp_:Array = [
125,150, 100,100, 150,100, 20,150, 230,150,
80,250, 170,250, 70,350, 180,350];
private var ks_:Array = [
1,2,1, 1,0,1, 2,0,1, 0,3,1, 0,4,1,
0,5,1, 5,6,1, 0,6,1, 5,7,1, 6,8,1,
1,3,0, 1,5,0, 3,5,0,
2,4,0, 2,6,0, 4,6,0,
5,8,0, 6,7,0, 7,8,0,
];
private var k_:Number;
public function RagDoll() {
rect_ = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
pts_ = new Vector.<VP>;
for (var i:int = 0; i < kp_.length; i+=2) {
var p:VP = new VP(kp_[i], kp_[i+1]);
addChild(p);
pts_.push(p)
}
k_ = 1 / 32;
sticks_ = new Vector.<VS>;
springs_ = new Vector.<VS>;
for (i = 0; i < ks_.length; i+=3) {
var s:VS = new VS(pts_[ks_[i]], pts_[ks_[i+1]],
ks_[i+2] ? 1 : k_);
sticks_.push(s);
if (!ks_[i+2]) springs_.push(s);
}
addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
var t:TextField = new TextField();
t.autoSize = TextFieldAutoSize.LEFT;
t.text = "Mouse click ... Jump\n" +
"Up arrow key ... Tense\n" +
"Down arrow key ... Loose";
addChild(t);
}
private function onEnterFrame(e:Event):void {
for (var i:int = pts_.length - 1; i >= 0; i--) {
var p:VP = pts_[i];
p.y += .5;
p.update();
p.constrain(rect_);
}
for (i = sticks_.length - 1; i >= 0; i--) {
sticks_[i].update();
}
graphics.clear();
for (i = sticks_.length - 1; i >= 0; i--) {
sticks_[i].draw(graphics);
}
}
private function onMouseDown(e:MouseEvent):void {
pts_[0].y -= 100;
}
private function onKeyUp(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.UP && k_ <= 0.5)
k_ *= 2;
else if (e.keyCode == Keyboard.DOWN && k_ > 1.0/256)
k_ /= 2;
for (var i:int = springs_.length - 1; i >= 0; i--) {
springs_[i].k = k_;
}
}
}
}
import flash.display.Graphics
import flash.geom.Rectangle;
import flash.display.Sprite;
class VP extends Sprite {
public var x_:Number;
public var y_:Number;
public var px_:Number;
public var py_:Number;
public function VP(ax:Number, ay:Number) {
x = px_ = ax;
y = py_ = ay;
graphics.beginFill(0);
graphics.drawCircle(0, 0, 4);
graphics.endFill();
}
public function update():void {
var t:Number;
t = x; x = 2 * x - px_; px_ = t;
t = y; y = 2 * y - py_; py_ = t;
}
public function constrain(r:Rectangle):void {
x = Math.max(r.left, Math.min(r.right, x));
y = Math.max(r.top, Math.min(r.bottom, y));
}
override public function set x(v:Number):void {
x_ = v;
super.x = x_;
}
override public function set y(v:Number):void {
y_ = v;
super.y = y_;
}
override public function get x():Number {
return x_;
}
override public function get y():Number {
return y_;
}
}
class VS {
private var pa_:VP;
private var pb_:VP;
private var len_:Number;
private var k_:Number;
public function VS(pa:VP, pb:VP, k:Number) {
pa_ = pa;
pb_ = pb;
len_ = Math.sqrt((pa_.x-pb_.x) * (pa_.x-pb_.x) +
(pa_.y-pb_.y) * (pa_.y-pb_.y));
k_ = k;
}
public function update():void {
var dx:Number = pb_.x - pa_.x;
var dy:Number = pb_.y - pa_.y;
var cl:Number = Math.sqrt(dx * dx + dy * dy);
var df:Number = len_ - cl;
var of:Number = df * dx / cl / 2 * k_;
pa_.x -= of; pb_.x += of;
of = df * dy / cl / 2 * k_;
pa_.y -= of; pb_.y += of;
}
public function draw(g:Graphics):void {
g.lineStyle(0, 0, k_);
g.moveTo(pa_.x, pa_.y);
g.lineTo(pb_.x, pb_.y);
}
public function set k(v:Number):void { k_ = v; }
}