MakeCircleDrop

by darman
当たり判定を実装する
ReleaseOutsideがうまく取れない…

♥0 | Line 141 | Modified 2009-07-30 11:28:26 | MIT License
play

ActionScript3 source code

/**
 * Copyright darman ( http://wonderfl.net/user/darman )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/96jo
 */

/*

当たり判定を実装する
ReleaseOutsideがうまく取れない…

*/


package  
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	
	[SWF (width = "500", height = "500", frameRate = "60", backgroundColor = "0x333333")]
	
	public class MakeCircleDrop extends Sprite
	{
		
		public function MakeCircleDrop() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event=null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			var timer:Timer = new Timer(1500,10);
			timer.addEventListener(TimerEvent.TIMER, makingCircle );
			//timer.start();
			
			makingCircle();
		}
		
		private function makingCircle(e:TimerEvent = null):void 
		{
			var makeCircleDropAnime:MakeCircleDropAnime = new MakeCircleDropAnime();
			addChild(makeCircleDropAnime);
		}
		
	}
}


import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;

class MakeCircleDropAnime extends Sprite
{
	private var angle:int = 0;
	private var radian:Number = 0;	//角度
	private var radius:Number = 50;	//半径
	
	private var centerX:int;
	private var centerY:int;
	
	private var speed:int = 20;
	
	private var xs:Number = 0;
	private var ys:Number = 0;
	
	
	public function MakeCircleDropAnime()
	{
		if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
	}
	
	private function init(e:Event=null):void
	{
		removeEventListener(Event.ADDED_TO_STAGE, init);
		
		centerX = stage.stageWidth / 2;
		centerY = stage.stageHeight / 2;
		
		var circle:Sprite = new Sprite();
		circle.graphics.lineStyle(1, 0x0, 1);
		circle.graphics.moveTo(0, 0);
		circle.graphics.beginFill(0xff0000);
		circle.x = Math.floor( Math.random() * stage.stageWidth );
		circle.y = Math.floor( Math.random() * (stage.stageHeight/2) ) + 10;
		addChild(circle);
		circle.buttonMode = true;
		
		circle.addEventListener(Event.ENTER_FRAME, makeCircleAnime );
	}
	
	private function makeCircleAnime(e:Event):void
	{
		xs = Math.cos(angle * Math.PI / 180) * radius;
		ys = Math.sin(angle * Math.PI / 180) * radius;
		
		angle += speed;
		angle %= 360;
		
		e.target.graphics.lineTo(xs, ys);
		
		if ( angle == 0 )
		{
			e.target.graphics.endFill();
			e.target.cacheAsBitmap = true;
			e.target.removeEventListener(Event.ENTER_FRAME, makeCircleAnime);
			e.target.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			e.target.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			e.target.addEventListener(Event.ENTER_FRAME, dropCircle );
		}
	}
	
	
	//オイラー法 (フレームレートでアニメーションが左右されない) 
	private var vx:int = 0;
	private var vy:int = -30;
	private var g:Number = 9.8;	//重力加速度
 	// wonderflでは変数宣言の際に掛け算などの計算がされてない 1フレーム時間(微分) * 補正
	private var dt:Number;
	private var repulsion:Number = -0.7;	//反発係数
	//private var friction:Number = 0.9999;//空気摩擦
	
	private function dropCircle(e:Event):void
	{
		dt = 1 / 60 * 15
		
		//重力
		vy += g * dt;
		
		e.target.x += vx * dt;
		e.target.y += vy * dt;
		e.target.rotation += vx * dt;
		
		// 地面に当たったとき
		// e.target.widthで当たり判定すると回転させるとrectの横幅とるから上手く転がらない
		//if(e.target.x + e.target.width > stage.stageWidth)
		if(e.target.x + radius > stage.stageWidth)
		{
			e.target.x  = stage.stageWidth - radius;
			vx = vx * repulsion;
		}
		else if(e.target.x - radius < 0)
		{
			e.target.x  = 0 + radius;
			vx = vx * repulsion;
		}
		if(e.target.y + radius > stage.stageHeight)
		{
			e.target.y  = stage.stageHeight - radius;
			vy = vy * repulsion;
			vx += ( 0 - vx) * 0.01;	//地面との摩擦
		}
		else if(e.target.y - radius < 0)
		{
			e.target.y  = + radius;
			vy = vy * repulsion;
		}
	}
	
	private var targetNowXPos:Number = 0;
	private var targetNowYPos:Number = 0;
	private var targetPreXPos:Number = 0;
	private var targetPreYPos:Number = 0;
	
	private function mouseDownHandler(e:MouseEvent):void
	{
		e.target.removeEventListener(Event.ENTER_FRAME, dropCircle);
		e.target.addEventListener(Event.ENTER_FRAME, dragMove );
		
		e.target.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		//stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
	}
	
	private function mouseUpHandler(e:MouseEvent):void
	{
		e.target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler );
		//stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		
		e.target.addEventListener(Event.ENTER_FRAME, dropCircle);
		e.target.removeEventListener(Event.ENTER_FRAME, dragMove );
		
		vx = targetNowXPos;
		vy = targetNowYPos;
	}
	
	private function dragMove(e:Event):void 
	{
		e.target.x = mouseX;
		e.target.y = mouseY;
		
		//初速を計算
		targetNowXPos = (e.target.x - targetPreXPos) * 3.5;
		targetNowYPos = (e.target.y - targetPreYPos) * 3.5;
		targetPreXPos = e.target.x;
		targetPreYPos = e.target.y;
	}
	
	
	
}