Murayama blog.

プログラミング教育なブログ

スロー


本日ラストのお題はスロー。


スロー。投げるっていう意味ね。スロー。
昔、ミッシェルガンエレファントの歌にスローって曲があったね。
あの花咲く頃に石を投げつけたいね。


さて、そんなロックなテーマですが、
実行結果はこんなかんじです。
ボールをドラッグして、投げるようなかんじでドロップするとボールが飛んでいきます。
うん、日本語って難しいね。


で、コード。


今回のポイントはたくさんあるんだけど、
mouseDownイベント内で、既存のenterFrameイベントを削除して、
スピード計測用のtrackVelocityメソッドを追加してるのがポイントです。
mouseUpイベントではその逆のことをして、元に戻してるかんじです。


で、そのスピードを算出するメソッドtrackVelocityはこんなかんじ。

		private function trackVelocity(evt:Event):void{
			// 今のマウスの位置と、前のフレームのマウスの位置からスピードを算出
			vx = mouseX - preX
			vy = mouseY - preY
			preX = mouseX;
			preY = mouseY
		}

ちょっとアニメーションの復習をしておくと、
現在地と、スピードがわかっている場合は、

新しい位置 = 現在地 + スピード

のようなかんじでアニメーションを定義します。


ってことは、スピードを求めるには、

スピード = 新しい位置 − 現在地

になるわけです。
trackVelocityメソッドではそれをしてるだけ。


ただし、マウスダウンしてすぐに現在地が必要なので、
mouseDownメソッドの最初でも現在地を記録しています。

		private function onMouseDown_ball(evt:MouseEvent):void
		{
			// マウスの位置をセット
			preX = mouseX;
			preY = mouseY;


最後にコード。

package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	public class Throwing extends Sprite
	{
		private var ball:Ball;
		private var vx:Number = 0;
		private var vy:Number = 0;
		private var bounce:Number = -0.7;
		private var gravity:Number = 0.5;
		
		private var preX:Number = 0
		private var preY:Number = 0
				
		public function Throwing()
		{
			init();
		}
		
		private function init():void{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			ball = new Ball;
			addChild(ball);
			
			ball.x = 200;
			ball.y = 200;
			
			vx = Math.random() * 10 -5;
			vy = -10;
			
			ball.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown_ball);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		private function onEnterFrame(evt:Event):void
		{
			vy += gravity;
			ball.x += vx;
			ball.y += vy;
			
			var left:Number = 0;
			var right:Number = stage.stageWidth;
			var top:Number = 0;
			var bottom:Number = stage.stageHeight;

			if(ball.x + ball.radious > right){
				ball.x = right - ball.radious;
				vx *= bounce;
			}else if(ball.x - ball.radious < left){
				ball.x = left + ball.radious;
				vx *= bounce;
			}

			if(ball.y + ball.radious > bottom){
				ball.y = bottom - ball.radious;
				vy *= bounce;
			}else if(ball.y - ball.radious < top){
				ball.y = top + ball.radious;
				vy *= bounce;
			}
		}

		private function trackVelocity(evt:Event):void{
			// 今のマウスの位置と、前のフレームのマウスの位置からスピードを算出
			vx = mouseX - preX
			vy = mouseY - preY
			preX = mouseX;
			preY = mouseY
		}

		private function onMouseDown_ball(evt:MouseEvent):void
		{
			// マウスの位置をセット
			preX = mouseX;
			preY = mouseY;
			
			ball.startDrag();
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp_stage);
			// イベントの削除
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			// 計測メソッドを追加
			addEventListener(Event.ENTER_FRAME, trackVelocity);
		}

		private function onMouseUp_stage(evt:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp_stage);
			ball.stopDrag();
			// 計測メソッドを削除			
			removeEventListener(Event.ENTER_FRAME, trackVelocity);
			// イベントの復帰
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
	}
}

import flash.display.Sprite;

class Ball extends Sprite
{
	public var radious:Number;
	public var color:uint;
	public var vx:Number;
	public var vy:Number;

	public function Ball(radius:Number = 40, color:uint = 0xff0000)
	{
		this.radious = radius;
		this.color = color;
		init();
	}

	private function init():void{
		graphics.beginFill(color);
		graphics.drawCircle(0, 0, radious);
		graphics.endFill();
	}
}

以上、7章おしまい。


お、これでPart 2 基本的なモーションは終了!
やるじゃない。
ドラクエでいうたらロマリアに着いたようなかんじ?


でわ。