Forked from: _wonder's 複数のセグメントをリーチさせる:IK reach (4) diff:35 ひもがいっぱい:IK reach (5) _wonder forked:0favorite:5lines:93license : MIT License modified : 2010-06-29 18:57:47 Embed Tweet // forked from _wonder's 複数のセグメントをリーチさせる:IK reach (4) // forked from _wonder's 3つのセグメントをリーチさせる:IK reach (3) // forked from _wonder's リーチの仕組み:IK reach (2) // forked from _wonder's セグメントを描画:IK drag (1) package { import flash.display.Sprite; public class InverseKinematics extends Sprite { private var numRopes:Number = 20; public function InverseKinematics() { var posY:Number = stage.stageHeight / 2; for( var i:uint = 0; i < numRopes; i++ ){ var posX:Number = ( stage.stageWidth / numRopes ) * i; var rope:Rope = new Rope( posX, posY ); addChild( rope ); } } } } import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; class Rope extends Sprite { private var segments:Array; private var num:Number = 50; public function Rope(posX:Number, posY:Number) { segments = new Array(); for( var i:uint = 0; i < num; i++ ){ var seg:Segment = new Segment( 5, 2, 0x000000 ); addChild( seg ); segments.push( seg ); } seg.x = posX; seg.y = posY; addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function onEnterFrame(e:Event):void { var target:Point = reach(segments[0], mouseX, mouseY); for( var i:uint = 1; i < num; i++ ){ var seg:Segment = segments[i]; target = reach( seg, target.x, target.y) ; } for( i = num - 1; i > 0; i-- ){ var segA:Segment = segments[i]; var segB:Segment = segments[i-1]; position( segB, segA ); } } private function reach(seg:Segment, xPos:Number, yPos:Number):Point { var dx:Number = xPos - seg.x; var dy:Number = yPos - seg.y; var angle:Number = Math.atan2( dy, dx ); seg.rotation = angle * 180 / Math.PI; var w:Number = seg.getPin().x - seg.x; var h:Number = seg.getPin().y - seg.y; var tx:Number = xPos - w; var ty:Number = yPos - h; return new Point( tx, ty ); } private function position(segA:Segment, segB:Segment):void { segA.x = segB.getPin().x; segA.y = segB.getPin().y; } } import flash.display.Sprite; import flash.geom.Point; class Segment extends Sprite { private var color:uint; private var segmentWidth:Number; private var segmentHeight:Number; public var vx:Number = 0; public var vy:Number = 0; public function Segment(segmentWidth:Number,segmentHeight:Number,color:uint=0xffffff){ this.segmentWidth = segmentWidth; this.segmentHeight = segmentHeight; this.color = color; init(); } public function init():void { //セグメントの描画 graphics.lineStyle( 0 ); graphics.beginFill( color ); graphics.drawRoundRect( -segmentHeight / 2, -segmentHeight / 2, segmentWidth+segmentHeight, segmentHeight, segmentHeight, segmentHeight ); graphics.endFill(); //ピン graphics.drawCircle( 0, 0, 2 ); graphics.drawCircle( segmentWidth, 0, 2 ); } public function getPin():Point { var angle:Number = rotation * Math.PI / 180; var xPos:Number = x + Math.cos( angle ) * segmentWidth; var yPos:Number = y + Math.sin( angle ) * segmentWidth; return new Point( xPos, yPos ); } } Code Fullscreen Preview Fullscreen satosu MacEvely Thy mastafrog Monica.Wader.. : Rope ik reach target rotation Point Math.atan2 mouseY mouseX addChild Math.PI addEventListener push Math.cos Event.ENTER_FRAME Math.sin Event Array uint Sprite Number