In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

IKhandle and Doll

Drag a red circles
/**
 * Copyright whirlpower ( http://wonderfl.net/user/whirlpower )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wpb4
 */

/*
 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;
        }
    }