// forked from Event's Human Clock /** * 時:曲がっている足の位置 * 分:伸びている足の位置 * 秒:両腕の傾き(腕同士が重なる側が秒針の方向) * * ・表示時間に応じて筋肉が増加。 * ・時刻に応じて体の色が変化。 * ・画面クリックで腕の上下動を反転。(何もしなくても1分毎に自動反転) * * IK制御に関しては narutohyper さんの IK Bone Sample を使わせていただいてます。 * http://wonderfl.net/c/tj5H */ package { import flash.display.Sprite; import flash.geom.Point; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import net.hires.debug.Stats; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.tweens.ITween; import org.libspark.betweenas3.easing.*; import org.libspark.betweenas3.events.TweenEvent; import frocessing.color.FColor; import frocessing.color.ColorHSV; import flash.utils.Timer; import flash.display.StageAlign; import flash.display.StageScaleMode; [SWF(width = 465, height = 465, frameRate = 60)] public class HumanClock extends Sprite { private var _stageW:Number; private var _stageH:Number; private static const MUSCLE_GAIN:Number = .01; //一回の動作での筋肉増加値 //ボーン制御用のコントロールポイント private var _armLPt:Point = new Point(); private var _armRPt:Point = new Point(); private var _legLPt:Point = new Point(); private var _legRPt:Point = new Point(); private var _footLPt:Point = new Point(); private var _footRPt:Point = new Point(); // private var _ika:IKArmature2d; private var _IKBones:Vector.<IKBone2d>; private var _legL:IKBone2d; private var _legR:IKBone2d; private var _footL:IKBone2d; private var _footR:IKBone2d; private var _armL:IKBone2d; private var _armR:IKBone2d; private var _head:IKBone2d; private var _armIT:ITween; //腕のトゥイーン private var _legIT:ITween; //脚のトゥイーン private var _nowSeconds:Number; private var _isArmUp:Boolean; //腕を上げるか下げるか private var _isHoursLegL:Boolean; //左脚で時刻を示すか private var _oldHAngle:Number = 0; //針の角度を保持(時) private var _oldMAngle:Number = 0; //針の角度を保持(分) // private var _musRatio:Number = 0; //現在の筋肉増加率 0~1 private var _musTimer:Timer; //筋肉増加タイマー private var _reverseCount:Number = 0; public function HumanClock() { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; _stageW = stage.stageWidth; _stageH = stage.stageHeight; //addChild( new Stats() ); graphics.beginFill (0x000000, 1); graphics.drawRect (0, 0, _stageW , _stageH); var clockDisk:Sprite = new ClockDisk(); clockDisk.x = _stageW/2; clockDisk.y = _stageH/2; addChild( clockDisk ); _musTimer = new Timer(2000, 1); _musTimer.addEventListener(TimerEvent.TIMER, musTimerHandler); //アーマチュアの作成 _ika = new IKArmature2d(); //ボーンの作成 _IKBones = new Vector.<IKBone2d>(); // _footL = makeIKBone('ankleLeft', 30, -120, 0x6D6D6D, 0x616161, 0); _ika.setBone( _footL ); _legL = makeIKBone('lowerFootLeft', 70, -180, 0x898989, 0x6D6D6D, 1); _ika.setBone( _legL ); _ika.setBone(makeIKBone('upperFootLeft', 80, -180, 0xA7A7A7, 0x898989, 2)); _ika.setBone(makeIKBone('waistLeft', 20, -120, 0xA7A7A7, 0xA7A7A7, 2)); // _footR = makeIKBone('ankleRight', 30, 120, 0x6D6D6D, 0x616161, 0); _ika.setBone( _footR ); _legR = makeIKBone('lowerFootRight', 70, 180, 0x898989, 0x6D6D6D, 1); _ika.setBone( _legR ); _ika.setBone(makeIKBone('upperFootRight', 80, 180, 0xA7A7A7, 0x898989, 2)); _ika.setBone(makeIKBone('waistRight', 20, 120, 0xA7A7A7, 0xA7A7A7, 2)); // _ika.setBone(makeIKBone('body', 30, 0, 0xA7A7A7, 0xA7A7A7, 1.5)); _ika.setBone(makeIKBone('belly', 30, 0, 0xA7A7A7, 0xC3C3C3, 2)); _ika.setBone(makeIKBone('breast', 45, 0, 0xC3C3C3, 0xDADADA, 3)); // _ika.setBone(makeIKBone('handLeft',20,-180, 0x979797, 0x909090, 0)); _armL = makeIKBone('lowerArmLeft',50,-170, 0xABABAB, 0x959595, 2); _ika.setBone( _armL ); _ika.setBone(makeIKBone('upperArmLeft',45,-150, 0xC4C4C4, 0xADADAD, 3)); _ika.setBone(makeIKBone('shoulderLeft',40,-100, 0xDBDBDB, 0xC9C9C9, 3)); // _ika.setBone(makeIKBone('handRight', 20, 180, 0x979797, 0x909090, 0)); _armR = makeIKBone('lowerArmRight',50,170, 0xABABAB, 0x959595, 2); _ika.setBone(_armR); _ika.setBone(makeIKBone('upperArmRight',45,150, 0xC4C4C4, 0xADADAD, 3)); _ika.setBone(makeIKBone('shoulderRight',40,100, 0xDBDBDB, 0xC9C9C9, 3)); // _ika.setBone(makeIKBone('neck', 25, 0, 0xE0E0E0, 0xE2E2E2, 2)); _head = makeIKBone('head', 40, 0, 0xE5E5E5, 0xFFFFFF, 0); _ika.setBone( _head ); //ボーンをジョイント _ika.joint('root', 'body'); _ika.joint('root', 'waistRight'); _ika.joint('root', 'waistLeft'); _ika.joint('body', 'belly'); _ika.joint('belly', 'breast'); // _ika.joint('breast', 'neck'); _ika.joint('neck', 'head'); // _ika.joint('breast', 'shoulderRight'); _ika.joint('breast', 'shoulderLeft'); _ika.joint('shoulderRight','upperArmRight'); _ika.joint('shoulderLeft', 'upperArmLeft'); _ika.joint('upperArmRight','lowerArmRight'); _ika.joint('upperArmLeft','lowerArmLeft'); _ika.joint('lowerArmRight','handRight'); _ika.joint('lowerArmLeft', 'handLeft'); // _ika.joint('waistRight','upperFootRight'); _ika.joint('waistLeft','upperFootLeft'); _ika.joint('upperFootRight','lowerFootRight'); _ika.joint('upperFootLeft', 'lowerFootLeft'); _ika.joint('lowerFootRight','ankleRight'); _ika.joint('lowerFootLeft','ankleLeft'); // addChild(_ika); _ika.x = _stageW/2; _ika.y = _stageH/2; // initMove(); changeColor(); addEventListener(Event.ENTER_FRAME, enterFrameHandler); stage.addEventListener(MouseEvent.CLICK, onMClickHandler); } private function makeIKBone($id:String, $length:Number, $rotation:Number, $colorA:Number, $colorB:Number, $mus:Number):IKBone2d { var ikBone:IKBone2d = new IKBone2d($id, $length, $rotation, $colorA, $colorB, $mus); _IKBones.push( ikBone ); return ikBone; } private function onMClickHandler(e:MouseEvent):void { _isArmUp = !_isArmUp; _reverseCount = -1; } private function initMove():void { var ca:Object = getClockHandAngle( new Date ); //足を動かす var tObjLegL:Object = getLegTweenPt( ca.h, ca.m, _oldHAngle, _oldMAngle, _isHoursLegL, true ); var tObjLegR:Object = getLegTweenPt( ca.h, ca.m, _oldHAngle, _oldMAngle, _isHoursLegL, false ); _isHoursLegL = !_isHoursLegL; // _legLPt.x = tObjLegL.legGoalX; _legLPt.y = tObjLegL.legGoalY; _legRPt.x = tObjLegR.legGoalX; _legRPt.y = tObjLegR.legGoalY; _footLPt.x = tObjLegL.footGoalX; _footLPt.y = tObjLegL.footGoalY; _footRPt.x = tObjLegR.footGoalX; _footRPt.y = tObjLegR.footGoalY; // _oldHAngle = ca.h; _oldMAngle = ca.m; } private function getClockHandAngle($time:Date):Object { var h:Number = $time.hours; var m:Number = $time.minutes; var s:Number = $time.seconds; var ca:Object = new Object(); ca.h = ( ((h % 12) * 30) + (m / 2) +270 )%360; ca.m = ( (m * 6) +270 )%360; ca.s = ( s * 6 +270 )%360; return ca; } private function enterFrameHandler(e:Event):void { var time:Date = new Date(); if ( _nowSeconds != time.seconds ) { _nowSeconds = time.seconds; var ca:Object = getClockHandAngle( time ); if(_nowSeconds%5 == 0){ reverseCountUp(); //腕を動かす var tObjArmL:Object = getArmTweenPt( ca.s, _isArmUp, true ); var tObjArmR:Object = getArmTweenPt( ca.s, _isArmUp, false ); _isArmUp = !_isArmUp; // if(_armIT != null) _armIT.stop(); _armIT = BetweenAS3.serial( BetweenAS3.parallel( BetweenAS3.bezier(_armLPt, { x:tObjArmL.tempX, y:tObjArmL.tempY }, null, {x:tObjArmL.x, y:tObjArmL.y}, 2, Cubic.easeInOut), BetweenAS3.bezier(_armRPt, { x:tObjArmR.tempX, y:tObjArmR.tempY }, null, {x:tObjArmR.x, y:tObjArmR.y}, 2, Cubic.easeInOut) ), BetweenAS3.parallel( BetweenAS3.tween(_armLPt, { x:tObjArmL.goalX, y:tObjArmL.goalY }, null, 1, Elastic.easeOut), BetweenAS3.tween(_armRPt, { x:tObjArmR.goalX, y:tObjArmR.goalY }, null, 1, Elastic.easeOut) ) ); _armIT.play(); _musTimer.start(); } if(_nowSeconds%10 == 0){ //足を動かす var tObjLegL:Object = getLegTweenPt( ca.h, ca.m, _oldHAngle, _oldMAngle, _isHoursLegL, true ); var tObjLegR:Object = getLegTweenPt( ca.h, ca.m, _oldHAngle, _oldMAngle, _isHoursLegL, false ); _isHoursLegL = !_isHoursLegL; // if(_legIT != null) _legIT.stop(); _legIT = BetweenAS3.parallel( BetweenAS3.delay(BetweenAS3.bezier(_legLPt, { x:tObjLegL.legGoalX, y:tObjLegL.legGoalY }, null, {x:tObjLegL.legCtX, y:tObjLegL.legCtY}, 1.5, Cubic.easeInOut), tObjLegL.delay), BetweenAS3.delay(BetweenAS3.bezier(_legRPt, { x:tObjLegR.legGoalX, y:tObjLegR.legGoalY }, null, {x:tObjLegR.legCtX, y:tObjLegR.legCtY}, 1.5, Cubic.easeInOut), tObjLegR.delay), BetweenAS3.delay(BetweenAS3.bezier(_footLPt, { x:tObjLegL.footGoalX, y:tObjLegL.footGoalY }, null, {x:0, y:0}, 1.5, Cubic.easeInOut), tObjLegL.delay), BetweenAS3.delay(BetweenAS3.bezier(_footRPt, { x:tObjLegR.footGoalX, y:tObjLegR.footGoalY }, null, {x:0, y:0}, 1.5, Cubic.easeInOut), tObjLegR.delay) ); _legIT.play(); // _oldHAngle = ca.h; _oldMAngle = ca.m; } } _legL.boneMove(new Point(_legLPt.x, _legLPt.y), -40); _legR.boneMove(new Point(_legRPt.x, _legRPt.y), -40); _footL.boneMove(new Point(_footLPt.x, _footLPt.y), -20); _footR.boneMove(new Point(_footRPt.x, _footRPt.y), -20); _armL.boneMove(new Point(_armLPt.x, _armLPt.y), -35); _armR.boneMove(new Point(_armRPt.x, _armRPt.y), -35); _head.boneMove(new Point(0, -190), -70); } private function reverseCountUp():void { _reverseCount++; if(_reverseCount >= 12){ _reverseCount = 0; _isArmUp = !_isArmUp; } } private function musTimerHandler(e:TimerEvent):void { changeMuscle(); changeColor(); } private function changeMuscle():void { _armIT.removeEventListener(TweenEvent.COMPLETE, changeMuscle); _musRatio += MUSCLE_GAIN; if( _musRatio>1 ) _musRatio = 1; for(var i:uint=0; i<_IKBones.length; i++){ _IKBones[i].changeMuscul( _musRatio ); } } private function changeColor():void { for(var i:uint=0; i<_IKBones.length; i++){ _IKBones[i].drawBone( _oldHAngle ); } } // 脚のトゥイーン情報を返す private function getLegTweenPt( $hAngle:Number, $mAngle:Number, $oldHAngle:Number, $oldMAngle:Number, $isHoursLegL:Boolean, $isArmLeft:Boolean ):Object { var tweenObj:Object = new Object(); var legCtX:Array = new Array(); var legCtY:Array = new Array(); var legLength:Number = 130; //脚の半径 var diffLeg:Number; var angle:Number; var oldAngle:Number; if( ($isArmLeft && $isHoursLegL) || (!$isArmLeft && !$isHoursLegL) ){ //短針 angle = $hAngle; oldAngle = $oldMAngle; diffLeg = -70; tweenObj.delay = 3.5; }else{ //長針 angle = $mAngle; oldAngle = $oldHAngle; diffLeg = 0; tweenObj.delay = 3; } //ベジェトゥイーンのコントロールポイント legCtX.push( Math.cos((oldAngle-angle)*Math.PI/180)*20 ); legCtY.push( Math.sin((oldAngle-angle)*Math.PI/180)*20 ); tweenObj.legCtX = legCtX; tweenObj.legCtY = legCtY; // tweenObj.footCtX = 0; tweenObj.footCtY = 0; // tweenObj.legGoalX = Math.cos((angle+3)*Math.PI/180)*(legLength+diffLeg); tweenObj.legGoalY = Math.sin((angle+3)*Math.PI/180)*(legLength+diffLeg); // tweenObj.footGoalX = Math.cos(angle*Math.PI/180)*(legLength+diffLeg+35); tweenObj.footGoalY = Math.sin(angle*Math.PI/180)*(legLength+diffLeg+35); return tweenObj; } // 腕のトゥイーン情報を返す private function getArmTweenPt( $angle:Number, $isArmUp:Boolean, $isArmLeft:Boolean ):Object { var tweenObj:Object = new Object(); var armBase:Number = -100; var ctX:Array = new Array(); var ctY:Array = new Array(); var angle:Number; var turn:Number; //回転方向 var armLength:Number = 100; //腕の長さ var diffArm:Number = (_isArmUp)? 20 : 0; if($isArmLeft){ //左腕 angle = ($isArmUp)? $angle += 6 : $angle -= 205; turn = ($isArmUp)? 1 : -1; }else{ //右腕 angle = ($isArmUp)? $angle -= 6 : $angle -= 155; turn = ($isArmUp)? -1 : 1; } //ベジェトゥイーンのコントロールポイント ctX.push( Math.cos((angle+(160*turn))*Math.PI/180)*(armLength*1.5) ); ctY.push( Math.sin((angle+(160*turn))*Math.PI/180)*(armLength*1.5) +armBase); ctX.push( Math.cos((angle+(135*turn))*Math.PI/180)*(armLength*1.5) ); ctY.push( Math.sin((angle+(135*turn))*Math.PI/180)*(armLength*1.5) +armBase); ctX.push( Math.cos((angle+(90*turn))*Math.PI/180)*(armLength*1.5) ); ctY.push( Math.sin((angle+(90*turn))*Math.PI/180)*(armLength*1.5) +armBase); ctX.push( Math.cos((angle+(45*turn))*Math.PI/180)*(armLength*1.5) ); ctY.push( Math.sin((angle+(45*turn))*Math.PI/180)*(armLength*1.5) +armBase); tweenObj.x = ctX; tweenObj.y = ctY; //一時的なゴール tweenObj.tempX = Math.cos(angle*Math.PI/180)*(armLength+diffArm); tweenObj.tempY = Math.sin(angle*Math.PI/180)*(armLength+diffArm) +armBase; //最終的なゴール tweenObj.goalX = Math.cos(angle*Math.PI/180)*(armLength+diffArm-30); tweenObj.goalY = Math.sin(angle*Math.PI/180)*(armLength+diffArm-30) +armBase; return tweenObj; } } } import flash.display.Sprite; class IKArmature2d extends Sprite { private var _rootJoint:IKJoint2d; //基準となるジョイント private var _bones:Object; public function IKArmature2d () { _bones = new Object; _rootJoint = new IKJoint2d('root'); addChild(_rootJoint); } public function get bones():Object { return _bones; } public function setBone(value:IKBone2d):void { _bones[value.id]=value; addChild(value); } public function joint($boneA:String = null, $boneB:String = null):void { if ($boneA) { if ($boneA == 'root') { if (_bones[$boneB]) { _bones[$boneB].jointRoot(_rootJoint); } else { trace('Error:boneが存在しません。', $boneB + '=', _bones[$boneB]); } } else if (bones[$boneB] && bones[$boneA]) { _bones[$boneB].setParentBone(bones[$boneA]); _bones[$boneA].setChildBone(bones[$boneB]); } else { trace('Error:boneが存在しません。', $boneA + '=', _bones[$boneA], $boneA + '=', _bones[$boneB]); } } } } import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Point; import flash.display.Shape; import flash.geom.ColorTransform; import flash.geom.Matrix3D; import flash.geom.Point; import flash.geom.Vector3D; import flash.geom.Matrix; import frocessing.color.FColor; import frocessing.color.ColorHSV; class IKBone2d extends Sprite { public static const MOVE_BONE:String = 'move_bone'; private var _tailJoint:IKJoint2d; private var _parentBones:Vector.<IKBone2d>; private var _childBones:Vector.<IKBone2d>; private var _boneLength:Number; //ボーンの長さ private var _bone:Sprite; private var _id:String; //関連付けられたMesh2d private var _isRootJoint:Boolean = false; private var _clickPoint:Point; private var _gradA:Number; private var _gradB:Number; private var _mus:Number; //筋肉増加量 public function IKBone2d ($id:String='null', $length:Number=100, $rotation:Number=0, $colorA:Number=0x006600, $colorB:Number=0x006600, $mus:Number=1) { _id = $id; _clickPoint = new Point(); _parentBones = new Vector.<IKBone2d>(); _childBones = new Vector.<IKBone2d>(); _bone = new Sprite(); addChild(_bone); _tailJoint = new IKJoint2d( "default", $colorB ); addChild(_tailJoint) _boneLength = $length; drawBone(); changeTailJoint(_boneLength); rotationZ = $rotation; _mus = $mus; _gradA = $colorA / 0xFFFFFF; _gradB = $colorB / 0xFFFFFF; addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); } //ドラッグの仕組み private function onMouseOver(e:MouseEvent):void { changeColor(0xFF0000); } private function onMouseOut(e:MouseEvent):void { changeColor(); } private function onMouseDown(e:MouseEvent):void { _clickPoint = new Point(mouseX, mouseY); removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut); removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver); removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); stage.addEventListener(MouseEvent.MOUSE_UP, onMUpHandler); stage.addEventListener(MouseEvent.MOUSE_MOVE,onMMoveHandler); } private function onMUpHandler(event:MouseEvent):void { _clickPoint = new Point(0, 0); if (event.target != this) { changeColor(); } addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); stage.removeEventListener(MouseEvent.MOUSE_UP, onMUpHandler); stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMMoveHandler); } private function onMMoveHandler(e:MouseEvent/*$color:uint = 0x006600*/):void { move(_tailJoint, new Point(parent.mouseX, parent.mouseY), new Point(x, y),null,null,'mouseMove') //親と子両方に伝達 var i:uint; if (_childBones.length) { for (i = 0; i < _childBones.length;i++) { _childBones[i].parentMove(this,new Point(_tailJoint.jx+x, _tailJoint.jy+y)) } } if (_parentBones.length) { for (i = 0; i < _parentBones.length;i++) { _parentBones[i].childMove(this,new Point(x, y)) } } } /**************************** * 自動ボーン操作 */ public function boneMove($pt:Point, $deffNum:Number=NaN):void { if($deffNum) _clickPoint = new Point(0, $deffNum); move(_tailJoint, $pt, new Point(x, y),null,null,'mouseMove'); //親と子両方に伝達 var i:uint; if (_childBones.length) { for (i = 0; i < _childBones.length;i++) { _childBones[i].parentMove(this,new Point(_tailJoint.jx+x, _tailJoint.jy+y)) } } if (_parentBones.length) { for (i = 0; i < _parentBones.length;i++) { _parentBones[i].childMove(this,new Point(x, y)) } } _clickPoint = new Point(0, 0); } public function parentMove($target:IKBone2d,$pt:Point):void { move(null, $pt, new Point(_tailJoint.jx+x, _tailJoint.jy+y),$target,'parent') //親から回ってきたら、子に伝達 var i:uint; if (_childBones.length) { for (i = 0; i < _childBones.length;i++) { _childBones[i].parentMove(this,new Point(_tailJoint.jx+x, _tailJoint.jy+y)); } } } public function childMove($target:IKBone2d, $pt:Point):void { move(_tailJoint, $pt, new Point(x, y),$target) //子から回ってきたら、親に伝達 var i:uint; if (_parentBones.length) { for (i = 0; i < _parentBones.length;i++) { _parentBones[i].childMove(this,new Point(x, y)) } } } private function move($j:IKJoint2d, $p1:Point, $p2:Point, $target:IKBone2d = null , $type:String = null,$mode:String = null):void { var dx:Number = $p1.x-$p2.x; var dy:Number = $p1.y-$p2.y; var angle:Number = Math.atan2( dy, dx ); if (!$type) { rotationZ = angle * 180 / Math.PI + 90; } else { rotationZ = angle * 180 / Math.PI - 90; } //もし、headerJointが固定点(rootJoint)に繋がっていたら、動かさない if (!_isRootJoint) { if ($mode) { var v3d:Vector3D = new Vector3D(0 ,_clickPoint.y, 0); var mtx:Matrix3D = new Matrix3D(); mtx.prependRotation(rotationZ, Vector3D.Z_AXIS); v3d = mtx.transformVector(v3d); x = $p1.x - v3d.x y = $p1.y - v3d.y; } else if ($j) { x = $p1.x - $j.jx; y = $p1.y - $j.jy; } else { x = $p1.x; y = $p1.y; } } else { if ($target) { $target.parentMove(null,new Point(tailJoint.jx+x, tailJoint.jy+y)); } } } private function changeColor($color:Number=NaN):void { var tc:ColorTransform; if(!isNaN($color)){ tc = new ColorTransform() tc.color = $color; }else{ //割り当てた色を初期化 tc = new ColorTransform(1, 1, 1, 1, 0, 0, 0, 0); } transform.colorTransform = tc; } //終点ジョイントの座標を変換? private function changeTailJoint(value:Number):void { tailJoint.y = -value; tailJoint.v3d = new Vector3D(0,-_boneLength, 0); var mtx:Matrix3D = new Matrix3D(); mtx.prependRotation(rotationZ, Vector3D.Z_AXIS); tailJoint.v3d = mtx.transformVector(tailJoint.v3d); } //ボーンの回転 //単にrotationでもいいのだが、3D化に備えあえてrotationZ&Vector3D override public function set rotationZ(value:Number):void { super.rotationZ = value; tailJoint.v3d = new Vector3D(0,-_boneLength, 0); var mtx:Matrix3D = new Matrix3D(); mtx.prependRotation(value, Vector3D.Z_AXIS); tailJoint.v3d = mtx.transformVector(tailJoint.v3d); } override public function get rotationZ():Number { return super.rotationZ; } //終点ジョイント public function get tailJoint():IKJoint2d { return _tailJoint; } //JointBone(始点Jointを親BoneのtailJointに結合する) public function jointBone(value:IKBone2d):void { x = value.tailJoint.jx; y = value.tailJoint.jy; if(value){ x += value.x y += value.y } } //JointRoot(始点JointをrootJointに結合する) public function jointRoot(value:IKJoint2d):void { _isRootJoint = true; x = value.jx; y = value.jy; } //親Boneのセット public function setParentBone(value:IKBone2d):void { _parentBones.push(value); jointBone(value); } //子Boneのセット public function setChildBone(value:IKBone2d):void { _childBones.push(value); } public function get id():String { return _id; } // 筋肉量変化 public function changeMuscul( volume:Number ):void { _bone.scaleY = _mus*volume + 1; } public function drawBone( $colorAngle:Number=0 ):void { var rgbA:Object = FColor.HSVtoRGB($colorAngle+120-(60*(1-_gradA)), 1, _gradA); var colorA:Number = (rgbA.r << 16) | (rgbA.g << 8) | (rgbA.b); var rgbB:Object = FColor.HSVtoRGB($colorAngle+120-(60*(1-_gradB)), 1, _gradB); var colorB:Number = (rgbB.r << 16) | (rgbB.g << 8) | (rgbB.b); //bone画像の生成 _bone.graphics.clear(); var matrix:Matrix = new Matrix(); matrix.createGradientBox(_boneLength, _boneLength, 0, 0, 0); _bone.graphics.beginGradientFill("linear", [colorA, colorB], [1,1], [0, 255], matrix); _bone.graphics.moveTo(0, 0); _bone.graphics.lineTo(5, -7); _bone.graphics.lineTo(_boneLength-5, -2); _bone.graphics.lineTo(_boneLength, 0); _bone.graphics.lineTo(_boneLength-5, 2); _bone.graphics.lineTo(5, 7); _bone.graphics.endFill(); _bone.rotation=-90; // _tailJoint.changeColor(colorB); } } import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import flash.geom.Vector3D; class IKJoint2d extends Sprite { private var _v3d:Vector3D; private var _type:String; public function IKJoint2d ($type:String = 'default', $color:Number=0x787878) { _type = $type; _v3d = new Vector3D(0, 0, 0); if (_type == 'root') { //drawRoot( $color ); } else { changeColor( $color ); } } public function changeColor( $color:Number ):void { graphics.clear(); graphics.lineStyle(3, $color, 1); graphics.drawCircle(0, 0, 3); } public function set v3d(v:Vector3D):void { _v3d = v; } public function get v3d():Vector3D { return _v3d; } //rootJointの場合は、自分自身の位置を返す。 //defaultJointは、位置、回転変換された座標を返す。 public function get jx():Number { return _v3d.x; } public function get jy():Number { return _v3d.y; } public function get type():String { return _type; } } import flash.display.Sprite; import frocessing.color.FColor; import frocessing.color.ColorHSV; class ClockDisk extends Sprite { public function ClockDisk() { var h:Number = 160; //半径 for(var i:uint=0; i<60; i++){ var angle:Number = i*6; var radian:Number = angle*Math.PI/180; var rgb:Object = FColor.HSVtoRGB(angle+90, 1, 1); var color:Number = (rgb.r << 16) | (rgb.g << 8) | (rgb.b); var l:Number = (angle%30 == 0)? 5 : 1; //線の長さ graphics.lineStyle(0, color); graphics.moveTo(Math.cos(radian)*(h-l), Math.sin(radian)*(h-l)); graphics.lineTo(Math.cos(radian)*h, Math.sin(radian)*h); } } } MuscleClock