IKhandle and Doll Drag a red circles whirlpower forked:1favorite:26lines:246license : MIT License modified : 2010-07-23 18:22:32 Embed Tweet /* Drag a red circles */ package { import flash.display.*; import flash.events.Event; [SWF(width = 465, height = 465, frameRate = 30)] public class Main extends Sprite { private var doll : Doll; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); doll = new Doll(); addChild( doll ); } } } import flash.display.*; import flash.events.*; import flash.geom.Point; internal class NodeObject extends Sprite { private var _ikParent:DollParts; public function get ikParent():DollParts { return _ikParent; } public function set ikParent(v:DollParts):void { _ikParent = v; } private var _ikX:Number; public function get ikX():Number { positioning(); return _ikX; } private var _ikY:Number; public function get ikY():Number { positioning(); return _ikY; } public function NodeObject( _x:int, _y:int ):void { this.x = _x; this.y = _y; } private function positioning():void { var p : Point = parent.localToGlobal( new Point( x,y ) ); _ikX = _ikParent.globalToLocal( p ).x; _ikY = _ikParent.globalToLocal( p ).y; } } internal class IkTarget extends NodeObject { public function IkTarget( _x:int, _y:int ):void { super( _x, _y ); graphics.beginFill( 0xFF0000, 0.2 ); graphics.drawCircle( 0, 0, 15 ); graphics.endFill(); addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler ); } private function mouseDownHandler(e:MouseEvent):void { removeEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler ); startDrag(); addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler ); } private function mouseUpHandler(e:MouseEvent):void { removeEventListener( MouseEvent.MOUSE_UP, mouseUpHandler ); stopDrag(); addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler ); } } internal class Doll extends NodeObject { private var _rootTarget : IkTarget; // ルート移動用 private var _headTarget : IkTarget; // 頭のIK目標点 private var _bodyTarget : IkTarget; // 体のIK目標点 private var _leftArmTarget : IkTarget; // 左手のIK目標点 private var _rightArmTarget : IkTarget; // 右手のIK目標点 private var _leftLegTarget : IkTarget; // 左足のIK目標点 private var _rightLegTarget : IkTarget; // 右足のIK目標点 private var _head : DollParts; // 頭 private var _body : DollParts; // 体 private var _leftArm : DollParts; // 左手 private var _rightArm : DollParts; // 右手 private var _leftLeg : DollParts; // 左足 private var _rightLeg : DollParts; // 右足 public function Doll():void { super( 230, 300 ); init(); } public function init():void { var param/*SegmentParam*/:Array; // 体 param = new Array(); param.push( new SegmentParam( 20, 20 ) ); param.push( new SegmentParam( 20, 20 ) ); param.push( new SegmentParam( 20, 20 ) ); param.push( new SegmentParam( 20, 20 ) ); _body = setDollParts( this, param, 0, 0 ); _bodyTarget = setTarget( _body, _body, 0, -80 ); // 頭 param = new Array(); param.push( new SegmentParam( 50, 20 ) ); _head = setDollParts( _body.getSegmentAt(0), param, 50, 0 ); _headTarget = setTarget( _body.getSegmentAt(0), _head, 100, 0 ); // 左手 param = new Array(); param.push( new SegmentParam( 50, 20 ) ); param.push( new SegmentParam( 50, 20 ) ); _leftArm = setDollParts( _body.getSegmentAt(0), param, 40, -40 ); _leftArmTarget = setTarget( _body.getSegmentAt(0), _leftArm, -50, -100 ); // 右手 param = new Array(); param.push( new SegmentParam( 50, 20 ) ); param.push( new SegmentParam( 50, 20 ) ); _rightArm = setDollParts( _body.getSegmentAt(0), param, 40, 40 ); _rightArmTarget = setTarget( _body.getSegmentAt(0), _rightArm, -50, 100 ); // 左足 param = new Array(); param.push( new SegmentParam( 60, 20 ) ); param.push( new SegmentParam( 70, 20 ) ); _leftLeg = setDollParts( _body, param, -30, 0 ); _leftLegTarget = setTarget( this, _leftLeg, -30, 130 ); // 右足 param = new Array(); param.push( new SegmentParam( 60, 20 ) ); param.push( new SegmentParam( 70, 20 ) ); _rightLeg = setDollParts( _body, param, 30, 0 ); _rightLegTarget = setTarget( this, _rightLeg, 30, 130 ); _rootTarget = new IkTarget( 0, 0 ); addChild( _rootTarget ); addEventListener( Event.ENTER_FRAME, loop ); } private function setDollParts( _parent:DisplayObjectContainer, _param:Array, _x:int, _y:int ):DollParts { var parts : DollParts = new DollParts( _param ); parts.x = _x; parts.y = _y; _parent.addChild( parts ); return parts; } private function setTarget( _parent:DisplayObjectContainer, _ikParent:DollParts, _x:int, _y:int ):IkTarget { var target:IkTarget = new IkTarget( _x, _y ); target.ikParent = _ikParent; _parent.addChild( target ); return target } private function loop( event:Event ):void { _body.x = _rootTarget.x; _body.y = _rootTarget.y; _body.upDate( _bodyTarget.ikX, _bodyTarget.ikY ); _head.upDate( _headTarget.ikX, _headTarget.ikY ); _leftArm.upDate( _leftArmTarget.ikX, _leftArmTarget.ikY ); _rightArm.upDate( _rightArmTarget.ikX, _rightArmTarget.ikY ); _leftLeg.upDate( _leftLegTarget.ikX, _leftLegTarget.ikY ); _rightLeg.upDate( _rightLegTarget.ikX, _rightLegTarget.ikY ); } } internal class DollParts extends Sprite { private var segments /*Segment*/:Array; public function getSegmentAt( num:int ):Segment { return segments[ num ]; } public function DollParts( params/*SegmentParam*/:Array ):void { segments = new Array(); for each( var seg:SegmentParam in params ) { var segment : Segment = new Segment( seg ); addChild( segment ); segments.push( segment ); } } public function upDate( targetX:int, targetY:int ):void { var target : Point = new Point( targetX, targetY ); var leng : int = segments.length; for ( var i : int = 0; i < leng; i++ ) { target = reach( segments[i], target.x, target.y ); if ( i >= 1 ) { var pin : Point = segments[i].getPin(); segments[i-1].x = pin.x; segments[i-1].y = pin.y; } } } private function reach( segment:Segment, px:Number, py:Number ):Point { var dx:Number = px - segment.x; var dy:Number = py - segment.y; var angle:Number = Math.atan2(dy, dx); segment.rotation = angle * 180 / Math.PI; var pin : Point = segment.getPin(); var w : Number = pin.x - segment.x; var h : Number = pin.y - segment.y; var tx : Number = px - w; var ty : Number = py - h; return new Point(tx, ty); } } internal class Segment extends Sprite { private var _length : int; private var _width : int; private static var colors:Array = [ 0xff0000, 0x00ff00, 0x0000ff ]; private static var count:int = 0; public function Segment( segmentParam:SegmentParam ) { this._length = segmentParam.length; this._width = segmentParam.width; graphics.beginFill( colors[count%3], 0.2 ); graphics.drawRect( -_width / 2, -_width / 2, _width + _length, _width ); count++; graphics.drawCircle(0, 0, 4 ); graphics.drawCircle( _length, 0, 2); graphics.endFill(); mouseEnabled = false; } public function getPin():Point { var angle:Number = rotation * Math.PI / 180; var px:Number = x + Math.cos(angle) * _length; var py:Number = y + Math.sin(angle) * _length; return new Point( px, py ); } } internal class SegmentParam { public var length:int; public var width : int; public function SegmentParam( length:int, width:int ):void { this.length = length; this.width = width; } } Code Fullscreen Preview Fullscreen alexnotkin flashhawkmx tkinjo sayutampo takishiki zotin95 nabe termat sugi_cho Albert siouxcitizen.. PROT830 demouth Thy paq matsumos Murai carbonhci : 互动游戏 hacker_lra4m.. : bonecoboneco darman : IK _wonder : IK motikawa_rgm.. : IK nyamogera : IK asou_jp : IK clockmaker : ik maxcaffy : IK IK IKhandle boneco 互动 游戏 target push globalToLocal addEventListener removeEventListener DisplayObjectContainer drawCircle MouseEvent.MOUSE_DOWN colors localToGlobal Point mouseEnabled stopDrag startDrag MouseEvent.MOUSE_UP Event.ADDED_TO_STAGE endFill rotation beginFill stage sort new page view favorite forked pv472 forked from: IKhandle and Doll.. h_sakurai forked:0 favorite:1lines:441 (diff:295)