/* マウスに追従する動きで、下記のモノより面白そうな動きを作っていただけるとうれしいです。 Homingクラスの引数の値を変えたり、「シェイプ生成」の箇所を書き換えたりすると、また違った動きが作れるかもしれません。 使っている式は三つあります -------- ・古い位置に対し新しい位置への方向をもとめる式 参考文献 http://wonderfl.net/code/387527e7d537bfaa1b07c2b314cc2d457f2bf965 var radian:Number = Math.atan2((古いY座標 - 新しいY座標), (古いX座標 - 新しいX座標)); パーティクル.rotation = radian * 180 / Math.PI; ・古い位置と新しい位置の距離間をもとめる式 参考文献 http://www.procreo.jp/tutorial02.html var 距離:int = Math.sqrt ((新しいY座標 - 古いY座標) * (新しいY座標 - 古いY座標) + (新しいX座標 - 古いX座標) * (新しいX座標 - 古いX座標)); ・イージングの式 参考文献 http://blog.bonkura.jp/formula05.html 現在の値 += (目標値 - 現在の値) / スピード; -------- 何かバグってたらすいません・・。 01/04 いまいち汎用性のない書き方をしていたので、そこを直しました。 Homingクラスの引数は、ターゲットコンテナ、ポジションX、ポジションYの三つにしました。 */ package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; [SWF(backgroundColor = 0x000000, frameRate = 60)] public class Index extends Sprite { private var isTrue:Boolean = true; public function Index() { var textField:TextField = new TextField(); textField.textColor = 0xFFFFFF; textField.text = "クリックしながらドラッグしてね"; textField.width = 200; addChild(textField); stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); } private function mouseDownHandler(e:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); //切り替えスイッチ isTrue = !isTrue; } private function mouseUpHandler(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); } private function mouseMoveHandler(e:MouseEvent):void { //四角か丸を生成 if (isTrue === true) { Homing.to(stage, mouseX, mouseY); } else { Homing.to(stage, mouseX, mouseY, "circle", 0xffffff * Math.random (), 1, 1, 8); }; } } } import flash.display.DisplayObjectContainer; import flash.display.Shape; import flash.events.Event; class Homing { public function Homing() { //newしちゃだめ throw new Error("Homing is class only of static method"); } private static var oldX :Number; private static var oldY :Number; private static var currentX :Number; private static var currentY :Number; /** * @param container ターゲットコンテナ * @param positionX ポジションX * @param positionY ポジションY * @param type "square"か"circle"か * @param color 色 * @param createInterval 一回で出るパーティクルの数(大きすぎると重くなる) * @param minSize パーティクルの最小サイズ * @param maxSize パーティクルの最大サイズ * @param disperse パーティクルの散らばり具合 * @param speed パーティクルの進行方向へのスピード * @param distanceLimit 古いポジションと新しいポジションとの距離間の許容値 */ public static function to( container:DisplayObjectContainer, positionX:uint, positionY:uint, type:String = "square", color:int = 0xFFFFFF, createInterval:int = 1, minSize:int = 2, maxSize:int = 15, disperse:int = 15, speed:int = 50, distanceLimit:int = 10 ):void { //移動前のポジション oldX = currentX; oldY = currentY; //移動後のポジション currentX = positionX; currentY = positionY; //移動前に対して移動後への方向をもとめる var angle:Number = Math.atan2 (currentY - oldY, currentX - oldX); var distanceX:Number = Math.cos (angle); var distanceY:Number = Math.sin (angle); //移動前と移動後との距離をもとめる var distance:int = int(Math.sqrt ((currentY - oldY) * (currentY - oldY) + (currentX - oldX) * (currentX - oldX))); //古いポジションと新しいポジションとの距離間が10以上ならばパーティクルを出す(シャッとしたら出す) if (distance >= distanceLimit) { for (var i:int = 1; i <= createInterval; ++i) { //大きさ var radius:int = int(Math.random () * (maxSize - minSize)) + minSize; //散りぐあい var disperse:int; if ((Math.random() * 2 >> 0) == 1) { disperse = int(Math.random () * disperse) * ( -1); } else { disperse = int(Math.random () * disperse) * 1; }; //目的地 var targetX:int = currentX + disperse + speed * distanceX; var targetY:int = currentY + disperse + speed * distanceY; //ターゲットプロパティ var targetScaleX:int = 1; var targetScaleY:int = 1; //速度(2~5) var speed:int = (Math.random() * 4 >> 0) + 2; //登退退場切り替えジャッジ var judge:int = 1; //登場済みかどうか var isEmerged:Boolean = false; //シェイプ生成 var shape:Shape = new Shape(); shape.x = currentX; shape.y = currentY; shape.graphics.beginFill(color, 1); if (type == "circle") { shape.graphics.drawCircle( 0, 0, radius); }; if (type == "square") { shape.graphics.drawRect( -radius / 2, -radius / 2, radius, radius); }; //初期プロパティ shape.scaleX = 0; shape.scaleY = 0; shape.alpha = Math.random(); //addする container.addChild(shape); //動き shape.addEventListener ( Event.ENTER_FRAME, function(e:Event):void { //rotation(上に行ったら右回転下に行ったら左回転) shape.rotation -= ((targetY - shape.y) * speed) / 5; //x if (int(Math.abs(targetX - shape.x)) > judge) { shape.x += (targetX - shape.x) / 10; } else { shape.x = targetX; }; //y if (int(Math.abs(targetY - shape.y)) > judge) { shape.y += (targetY - shape.y) / 10; } else { shape.y = targetY; }; //scale if (Math.abs(targetScaleX - shape.scaleX) * 100 > judge && Math.abs(targetScaleY - shape.scaleY) * 100 > judge) { shape.scaleX += (targetScaleX - shape.scaleX) / speed; shape.scaleY += (targetScaleY - shape.scaleY) / speed; } else { shape.scaleX = targetScaleX; shape.scaleY = targetScaleY; //退場アニメーションへ移行 isEmerged = true; } //退場アニメーションへ if (isEmerged) { targetScaleY = 0; targetScaleX = 0; } //登場済みで透明になる処理が終わっていたら終了処理 if (isEmerged && shape.scaleX === targetScaleX && shape.scaleY === targetScaleY) { e.target.removeEventListener(Event.ENTER_FRAME, arguments.callee); //removeする shape.graphics.clear(); container.removeChild(shape); } } ); } } } } 軌跡 forked from: nengafl