
I finally started playing around with the new features of Flash CS4.
One thing I have been really curious to try out was the application of an inverse kinematic armature to a raw shape. The discovery that you can’t generate and apply joints and bones procedurally (you have to construct your armature using the Flash tool) was sort of a semi-anticipated disappointment, but hey, I guess you can’t have everything.
The good news is that you still can manipulate a hand-built, existing armature and its components using code, as the following quick example demonstrates.
Drag around the circular handle to deform the shape:
Please feel free to try out the following code yourself. All you need is a simple setup consisting of a shape with a few bones attached to it. The code will recursively walk through the hierarchy of bones/joints, find the last one, and attach the drag-handle and an IKMover object to it.
// Flash CS4 IKTest (C) edvardtoth.com package { import flash.display.*; import flash.events.*; import flash.geom.Point; import fl.ik.*; // Important: make sure your "type" armature-property is set to "runtime" instead of "authortime" public class IKTest extends Sprite { private var armature:IKArmature; private var currentJoint:IKJoint; private var currentJointPosition:Point; private var newPosition:Point; private var handle:Sprite; private var mover:IKMover; public function IKTest() { stage.scaleMode = StageScaleMode.NO_SCALE; stage.quality = StageQuality.HIGH; stage.align = StageAlign.TOP_LEFT; stage.showDefaultContextMenu = false; setupHandle(); addEventListener (Event.FRAME_CONSTRUCTED, startUp); } private function startUp (event:Event):void { removeEventListener (Event.FRAME_CONSTRUCTED, startUp); this.scrollRect = this.getRect(this); // finds the first IK armature in the hierarchy, and its root joint as the starting point armature = IKManager.getArmatureAt(0); currentJoint = armature.rootJoint; findEndJoint(); } // recursively iterates through the bones and joints to find the last one private function findEndJoint():void { if (currentJoint.numChildren != 0) { currentJoint = currentJoint.getChildAt(0); findEndJoint(); } else { // if the last joint is found, an IKMover and the drag-handle are attached to it currentJointPosition = currentJoint.position; mover = new IKMover (currentJoint, currentJointPosition); addChild (handle); handle.x = currentJointPosition.x; handle.y = currentJointPosition.y; addEventListener (Event.ENTER_FRAME, updateFrame); } } // matches the position of the last joint to the position of the handle private function updateFrame (event:Event):void { newPosition = new Point (handle.x, handle.y); mover.moveTo (newPosition); } // creates the circular handle sprite private function setupHandle():void { handle = new Sprite(); handle.graphics.lineStyle (4, 0x000000, 1.0, false, LineScaleMode.NORMAL); handle.graphics.beginFill (0x000000, 0.0); handle.graphics.drawCircle (0, 0, 20); handle.graphics.endFill(); handle.addEventListener (MouseEvent.MOUSE_DOWN, onDown); handle.addEventListener (MouseEvent.MOUSE_UP, onUp); } private function onDown (event:MouseEvent):void { event.currentTarget.startDrag(); } private function onUp (event:MouseEvent):void { event.currentTarget.stopDrag(); } } }
