In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

ビリヤードボールの原理

ビリヤードボールの原理
Get Adobe Flash player
by akira_odohira 21 May 2009
    Embed
/**
 * Copyright akira_odohira ( http://wonderfl.net/user/akira_odohira )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/5HQu
 */

/*
	ビリヤードボールの原理
*/
package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;
	//import utils.ExDebug;

	public class Circle extends Sprite{
		
		private var _cnt:int = 20;
		private var _timer:Timer;
		private var _spArr:Array = new Array();
		private var _ptArr:Array = new Array();
		//circleの初期設定
		private var _minRadius:uint = 30;
		private var _lengeRadius:uint = 20;
		private var _initV:Number = 4;
		//画面外
		private var _addV:Number = 0.4;
		private var _hosei:int = 00;
	
		public function Circle() {
		//	ExDebug.motitor(stage);
			init();
		}
		
		private function init():void {
			_spArr = new Array();
			_ptArr = new Array();
			setTimer();
			setListener();
		
			// triger
			//addCircle();
		}
		
		private function setTimer():void{
			_timer = new Timer(500, _cnt);
			_timer.addEventListener(TimerEvent.TIMER, addCircle, false, 0, true);
			//_timer.addEventListener(TimerEvent.TIMER_COMPLETE, addCircle, false, 0, true);
			_timer.start();
		}
			
		private function setListener():void{
			addEventListener(Event.ENTER_FRAME, motion, false, 0, true);
			addEventListener(Event.ENTER_FRAME, rendering, false, 0, true);
		}
			
		private function addCircle(e:TimerEvent = null):void {
			var radius:uint = Math.random() * _lengeRadius + _minRadius;
			drawCircle(radius);
			setPoint(radius);
		}
		
		private function drawCircle(radius:uint):void{
			var sp :Sprite = new Sprite();
			sp.graphics.beginFill(0, 1);
			sp.graphics.drawCircle(0, 0, radius );
			sp.graphics.endFill();
			sp.x = -500;
			addChild(sp);
			_spArr.push(sp);
		}
		
		private function setPoint(radius:uint):void{
			var pt:CirclePoint = new CirclePoint(radius, _initV);
			pt.x = -500;
			pt.y = stage.stageHeight >> 1;
			_ptArr.push(pt);
		}
		
		// circle1の座標計算
		private function motion(e:Event):void {
			var ptArr:Array = _ptArr;
			var length:uint = ptArr.length;
			var i:int, j:int;
			var pt:CirclePoint, pt0:CirclePoint, pt1:CirclePoint;
			var boo:Boolean;
		
			for (i = 0; i < length; i++ ) {
				pt = ptArr[i];
				pt.x += pt.vx;
				pt.y += pt.vy;
				if (pt.vx * pt.vx + pt.vy * pt.vy > 10) {
					pt.vx *= 0.98;
					pt.vy *= 0.98;
				}
				pt.rotation += ( -pt.vx + pt.vy) / 10;
				pt.rotation *= 0.99;
				checkWalls(pt);
			}
						
			for (i = 0; i < length; i++ ) {
				pt0 = ptArr[i];
				for (j = 0; j < length; j++ ) {
					pt1 = ptArr[j];
					if(pt0 != pt1) checkCollision( pt0, pt1);		
				}
			}
		}
		
		// 描画
		private function rendering(e:Event):void {
			var spArr:Array = _spArr;
			var ptArr:Array = _ptArr;
			var length:uint = spArr.length;
			var i:uint;
			var sp:Sprite;
			var pt:CirclePoint;
			for (i = 0; i < length; i++ ) {
				sp = spArr[i];
				pt = ptArr[i];
				sp.x = pt.x;
				sp.y = pt.y;
				sp.rotation = pt.rotation;
			}
		}
		
		// 円と円の衝突
		private function checkCollision(pt0:CirclePoint, pt1:CirclePoint):void {
			var dx:Number = pt1.x - pt0.x;
			var dy:Number = pt1.y - pt0.y;
			var dist:Number = Math.sqrt(dx * dx + dy * dy);
			if(dist < pt0.radius + pt1.radius)	{
				var angle:Number = Math.atan2(dy, dx);
				var sin:Number = Math.sin(angle);
				var cos:Number = Math.cos(angle);
				var v:Number = dist - (pt0.radius + pt1.radius);
				pt0.vx += (v / (pt0.radius * 10)) * cos;
				pt0.vy += (v / (pt0.radius * 10)) * sin;
			}
		}
		
		// エリア外に出たときの処理
		private function checkWalls(pt:CirclePoint):void{
			if (pt.x < -_hosei ) pt.vx += _addV;
			else if (pt.x > stage.stageWidth + _hosei) pt.vx += -_addV;
			if (pt.y < -_hosei) pt.vy = _addV;
			else if (pt.y > stage.stageHeight + _hosei) pt.vy = -_addV;
		}
		
	}
}

class CirclePoint {
	
	public var x:Number = 0;			// x
	public var y:Number = 0;			// y
	public var rotation:Number = 0;		// rotation
	public var vx:Number = 0;			// 速度 x
	public var vy:Number = 0;			// 速度 y
	public var vr:Number = 0;			// 速度 rotation
	public var radius:Number = 0; 		// 半径
	
	public function CirclePoint(radius:Number, v:Number) {
		this.radius = radius;
		this.vx = v + Math.random();
		this.vy = (Math.random() > 0.5)? v + Math.random() : -(v + Math.random());
	}
}