package {
	import flash.text.TextField;
	import flash.display.Sprite;
	import flash.events.*;
	import flash.utils.*;
	
	// ベースの設定
	[SWF(width="101",height="101",frameRate="24")]


	public class MyHit extends Sprite {
		
		private var actors:Array; // 動く物
		private var backgrounds:Array; // 背景物
		private var myMsg:TextField = new TextField();
		private var myTimer:Timer;
		
		public static var LIMIT_WIDTH:Number = 100;
		public static var LIMIT_HEIGHT:Number = 100;
		
		public function MyHit() {
		
			// コンテナの生成
			actors = new Array();
			backgrounds = new Array();
		
			var actor:MyCircle;
			// 円1の初期化
			actor = new MyCircle();
			actor.x = 20;
			actor.y = 50;
			actor.radius = 10;
			actor.speed = 10;
			actor.radian = Utils.toRadian(10);
			actor.color = 0xFF0000;
			actors.push(actor); // 配列に追加
			
			// 円2の初期化
			actor = new MyCircle();
			actor.x = 40;
			actor.y = 80;
			actor.radius = 10;
			actor.speed = 5;
			actor.radian = Utils.toRadian(-160);
			actor.color = 0x0000FF;
			actors.push(actor); // 配列に追加
			
			// 円3の初期化
			actor = new MyCircle();
			actor.x = 60;
			actor.y = 20;
			actor.radius = 10;
			actor.speed = 5;
			actor.radian = Utils.toRadian(0);
			actor.color = 0x00FF00;
			actors.push(actor); // 配列に追加
			
			var background:MyBox;
			// 四角1の初期化
			background = new MyBox();
			background.x = 00;
			background.y = 0;
			background.radius = 10;
			background.sizeX = LIMIT_WIDTH;
			background.sizeY = LIMIT_HEIGHT;
			background.color = 0x0000FF;
			backgrounds.push(background); // 配列に追加
			
			
			// タイマー設定
			myTimer = new Timer(100, 0);
			myTimer.addEventListener(TimerEvent.TIMER, sequence);
			myTimer.start();
			
			myMsg.mouseEnabled = false;
			myMsg.width = 600;
			myMsg.height = 600;

			// 動く物をベースに追加
			for each(var objActor:Sprite in actors)
			{
				addChild(objActor);
			}
			
			// 背景をベースに追加
			for each( var objBackground:Sprite in backgrounds)
			{
				addChild(objBackground);
			}
			addChild(myMsg);
			
		}
		
		public function sequence(e:TimerEvent):void{
		
			
			// 移動
			moves();
			
			// 限界チェック
			checkLimits();
			
		//	myMsg.text = circle1.radian.toString();
		//	myMsg.appendText("\n x:" + box1.x);
		//	myMsg.appendText("\n y:" + box1.y);
		//	myMsg.appendText("\n transX:" + box1.transX);
		//	myMsg.appendText("\n transY:" + box1.transY);
		//	myMsg.appendText("\n speed:" + box1.speed);
		//	myMsg.appendText("\n radius:" + box1.radius);
		//	myMsg.appendText("\n sizeX:" + box1.sizeX);
		//	myMsg.appendText("\n sizeY:" + box1.sizeY);
		
			// 衝突時処理
			checkHits();
			
			// 描画
			draws();
			
		}
		
		// 移動
		public function moves():void{
			for each(var objActor:MyCircle in actors)
			{
				objActor.move();
			}
		}
		
		// 限界チェック
		public function checkLimits():void{
			for each(var objActor:MyCircle in actors)
			{
				checkLimit(objActor);
			}
		}
		
		// オブジェクトの描画
		public function draws():void{
			// 描画
			for each(var objActor:MyCircle in actors)
			{
				objActor.draw();
			}
			
			// 描画
			for each(var objBackground:MyBox in backgrounds)
			{
				objBackground.draw();
			}
		}
		
		// 当たり判定
		public function checkHits():void{
			var tempActors:Array = actors.slice();
			
			for each(var target:MyCircle in actors){
				tempActors.shift(); // 先頭の要素を削除
				
				// 削除した要素とその後のオブジェクトを判定
				for each(var objActor:MyCircle in tempActors){
					checkHit(target, objActor);
				}
			}
		}
		
		// 当たり判定
		public function checkHit(spr1:MyCircle, spr2:MyCircle):void{
			if(spr1.hitTestObject(spr2)){
				
				spr1.radian = - Utils.convertPointToRadian(spr1.x, spr1.y, spr2.x, spr2.y);
				spr2.radian = - Utils.convertPointToRadian(spr2.x, spr2.y, spr1.x, spr1.y);
				
				// スピードの交換
				var tempSpped:Number;
				tempSpped = spr1.speed;
				spr1.speed = spr2.speed;
				spr2.speed = tempSpped;
			}
		}
		
		// 限界値反射
		public function checkLimit(spr:MyCircle):void{
			// 上
			if(spr.hitTestPoint(spr.x, 0, false)){
				spr.y = spr.radius;
				spr.radian = - spr.radian;
				
			}
			// 下
			else if(spr.hitTestPoint(spr.x, LIMIT_HEIGHT, false)){
				spr.y = LIMIT_HEIGHT - spr.radius;
				spr.radian = - spr.radian;
			}
			// 左
			if(spr.hitTestPoint(0, spr.y, false)){
				spr.x = spr.radius;
				spr.radian = Utils.toRadian(180) - spr.radian;
			}
			// 右
			else if(spr.hitTestPoint(LIMIT_WIDTH, spr.y, false)){
				spr.x = LIMIT_WIDTH - spr.radius;
				spr.radian = Utils.toRadian(180) - spr.radian;
			}
		}
		
	}
	
}


import flash.text.TextField;
import flash.events.MouseEvent;
import flash.display.Sprite;

// 円
class MyCircle extends Sprite {
	public var color:Number = 0xFFCC00;
	public var radius:Number = 10;
	public var transX:Number = 0;
	public var transY:Number = 0;
	public var radian:Number = 0.0;
	public var speed:Number = 0.0;
	
	public function draw():void{
		graphics.beginFill(color);
		graphics.drawCircle(0, 0, radius);
	}
	
	// 移動
	public function move():void{
		radian %= Utils.toRadian(360);
		
		transX = Math.cos(radian) * speed;
		if(radian < 0 && transX > 0){
		//	transX *= -1;
		}
		transY = -Math.sin(radian) * speed;
		
		x += transX;
		y += transY;
	}
}

// 四角
class MyBox extends Sprite {
	public var color:Number = 0xFFCC00;
	public var radius:Number = 10;
	public var transX:Number = 0;
	public var transY:Number = 0;
	public var radian:Number = 0.0;
	public var speed:Number = 0.0;
	public var lineWidth:Number = 1.0;
	public var sizeX:Number = 0;
	public var sizeY:Number = 0;
	
	public function draw():void{	
		graphics.lineStyle(lineWidth, color);
		graphics.moveTo(x, y);
		graphics.lineTo(x + sizeX, y);
		graphics.lineTo(x + sizeX, y + sizeY);
		graphics.lineTo(x, y + sizeY);
		graphics.lineTo(x, y);
	}
	
	// 移動
	public function move():void{
		radian %= Utils.toRadian(360);
		
		transX = Math.cos(radian) * speed;
		if(radian < 0 && transX > 0){
		//	transX *= -1;
		}
		transY = -Math.sin(radian) * speed;
		
		x += transX;
		y += transY;
	}
}

// Utilsクラス
class Utils{
	// 角度をラジアンに変換する
	static public function toRadian(angle:Number):Number{
		return angle * Math.PI / 180;
	}
	// ラジアンを角度に変換する
	static public function toRotation(rad:Number):Number{
		return rad * 180 / Math.PI;
	}
	// 2点の座標の角度をラジアンに変換する
	static public function convertPointToRadian(px1:Number, py1:Number, px2:Number, py2:Number):Number{
		return Math.atan2(py1 - py2, px1 - px2);
	}
}