flash on 2009-11-28

by purin
♥0 | Line 227 | Modified 2009-12-01 23:05:51 | MIT License
play

ActionScript3 source code

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

package{

	import flash.display.*;
	import flash.events.Event;

	[SWF(width="512",height="512",backgroundColor="0x999999")]

	public class main extends Sprite{

		private var _heroAI:AI = new AI();
		private var _enemyAI:AI = new AI();
		
		private var _hero:Charactor  = new Charactor( 50,50,0x00FF00,20,25,_heroAI);
		private var _enemy:Charactor = new Charactor(100,50,0xFF0FF0,20,25,_enemyAI);
		
		private function DrawPicture():void{
			addChild(_hero.pic);
			addChild(_hero.vfpic);
			addChild(_enemy.pic);
			addChild(_enemy.vfpic);
			addChild(_hero.deb.getText());
		}
		
		//ゲーム処理全般
		private function GameMaster(event:Event):void{
			_hero.brain.Rotate(1);
			_enemy.brain.Rotate(0);
			_hero.brain.CollisionCheck2(_enemy);
//			_hero.brain.CollisionCheck();
			
			//キャラの座標が変わるので、それにあわせて視野の座標も更新する
			_hero.Refleshvf();
			_enemy.Refleshvf();
			
			DrawPicture();
		}
		
		//初期化色々
		private function Init():void{
			_heroAI.myAI = _hero;
			_enemyAI.myAI = _enemy;
		}
		
		//全キャラの衝突の計算(後でグリット分割する)
/*		private function CollisionCheck():void{
		
			for(var i:int = 0;i<HERO_NUM;i++){
				for(var k:int = 0;k<ENEMY_NUM;k++){
				}
			}
		
		}
*/		
		//constractor
		public function main():void{
			Init();
			addEventListener(Event.ENTER_FRAME,GameMaster);
		}
	}
}

import flash.geom.Point;
import flash.display.*;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.text.TextField;

const HERO_NUM:uint = 1;
const ENEMY_NUM:uint = 1;
const TYPE_NUM:uint = 2;		//**_COLLISIONの数
const CHARACTOR_COLLISION:uint = 0;
const VIEW_COLLISION:uint = 1;
	
//キャラクタの基本設定を決めるクラス
class Charactor extends Sprite{

	private var _pic:Sprite;		//キャラの絵
	private var _brain:AI;			//AIセット用
	private var _vf:ViewPoint;		//視野座標
	private var _vfPic:Sprite;		//視野を表示する線
	private var _radius:uint;		//キャラの半径
	private var _viewSize:uint;		//視野の大きさ
	private var _color:uint;
	
	public var deb:Debug = new Debug(10,10);
	
	//自分との当たり判定の結果を入れる2次元配列([判定する種類の数][判定を行う相手の数])
	private var _coll:Array = new Array();
	
	//コンストラクタ(初期座標,色,半径,視野の広さ,AIクラス)
	public function Charactor(px:int,py:int,color:uint,radius:uint,size:uint,setAI:AI):void{
		_brain = setAI;
	
		_pic = new Sprite();
		_pic.x = px;
		_pic.y = py;
		_radius = radius;
		_viewSize = size;
		_color = color;
		
		_vfPic = new Sprite();
		
		_vf = new ViewPoint(_viewSize);
		//視野の座標とスプライトを更新
		Refleshvf();
		
		_pic.graphics.beginFill(color);
		_pic.graphics.drawCircle(0,0,_radius);
		_pic.graphics.endFill();
		
		//当たり判定結果の初期化
		for(var i:int=0;i<TYPE_NUM;i++){
			_coll[i] = new Array();
			for(var k:int=0;k<ENEMY_NUM;k++){
				_coll[i][k] = false;
			}
		}
		deb.setText("collision"+_coll[CHARACTOR_COLLISION][0]+"  "+_coll[VIEW_COLLISION][0]);

	}	
	
	//視野座標の更新色々
	public function Refleshvf():void{
	
		_vf.ViewRefresh(new Point(_pic.x,_pic.y));
		
		//視野を表す線の表示
		_vfPic.graphics.clear();
		_vfPic.graphics.lineStyle(1,0xFF0000);
		_vfPic.graphics.moveTo(_vf.vpos(0).x,_vf.vpos(0).y);
		_vfPic.graphics.lineTo(_vf.vpos(1).x,_vf.vpos(1).y);
		_vfPic.graphics.lineTo(_vf.vpos(2).x,_vf.vpos(2).y);
		_vfPic.graphics.lineTo(_vf.vpos(0).x,_vf.vpos(0).y);
	}
	
	//type:0->キャラ、1->視野
	public function collisionResult(type:int,num:int,result:Boolean):void{
		_coll[type][num] = result;
	}

	//getter
	public function get pic():Sprite{return (_pic);}
	public function get vfpic():Sprite{return (_vfPic);}
	public function get radius():int{return (_radius);}
	public function get brain():AI{return (_brain);}
	public function get vf():ViewPoint{return (_vf);}
	public function get size():uint{return (_viewSize);}
	public function get collision():Array{return (_coll);}

}

//衝突判定用クラス
class Collision {


	//視野に敵が入ったかの判定
	public function ViewCollision(my:Charactor,you:Charactor,you_num:int):void{

		//始点から敵の中心に対してのベクトル
		var vc:Array = [new Point(you.pic.x - my.vf.vpos(0).x, you.pic.y - my.vf.vpos(0).y),
						new Point(you.pic.x - my.vf.vpos(1).x, you.pic.y - my.vf.vpos(1).y),
						new Point(you.pic.x - my.vf.vpos(2).x, you.pic.y - my.vf.vpos(2).y)];
		
		//視野を構成するベクトルと、始点から敵の中心に対してのベクトル(vc)との外積
		var m:Array = [ MathPuls.VectorCross(my.vf.vpos(1),vc[0]),
						MathPuls.VectorCross(my.vf.vpos(2),vc[1]),
						MathPuls.VectorCross(my.vf.vpos[3],vc[2])];
		
		//視野を構成するベクトルと、始点から敵の中心に対してのベクトル(vc)との内積
		var n:Array = [ MathPuls.VectorDot(my.vf.vpos(1),vc[0]),
						MathPuls.VectorDot(my.vf.vpos(2),vc[1]),
						MathPuls.VectorDot(my.vf.vpos[3],vc[2])];
		
		//始点から円の中心に対してのベクトルの二乗
		var c:Array = [ MathPuls.VectorDot(vc[0],vc[0]),
						MathPuls.VectorDot(vc[1],vc[1]),
						MathPuls.VectorDot(vc[2],vc[2])];
		
		for(var i:int=0;i<3;i++){
			if(n[i] <= 0){
				if(you.radius >= Math.abs(m[i])/MathPuls.VectorLength(my.vf.vpos(i))){
					my.collisionResult(VIEW_COLLISION,you_num,true);
				}
			}
		}
		for(i=0;i<3;i++){
			if(n[i] >= 0){
				if(you.radius*you.radius >= c[i]){
					my.collisionResult(VIEW_COLLISION,you_num,true);
				}
			}
		}
		if(m[0] <= 0 && m[1] <= 0 && m[2] <= 0){
			my.collisionResult(VIEW_COLLISION,you_num,true);
		}
	}
	
	//キャラ同士の衝突判定
	public function CharactorCollision(my:Charactor,you:Charactor,you_num:int):void{
		var l_mypos:Point = new Point(my.pic.x,my.pic.y);
		var l_youpos:Point = new Point(you.pic.x,you.pic.y);
		
		if( MathPuls.VectorDistance(l_mypos,l_youpos) <= (my.radius+you.radius)){
			my.collisionResult(CHARACTOR_COLLISION,you_num,true);
		}
	}


}

//Aiの基底クラス
class AI extends Collision{

	private var _my:Charactor;
	
	public function CollisionCheck2(enemy:Charactor):void{
		CharactorCollision(_my,enemy,0);
		ViewCollision(_my,enemy,0);
	}

	public function CollisionCheck():void{
		if(_my.collision[VIEW_COLLISION][0]){
			var hit1:ColorTransform = new ColorTransform();
			hit1.color = 0xFFFFFF;
			_my.pic.transform.colorTransform = hit1;
		}
		else{
			var hit2:ColorTransform = new ColorTransform();
			hit2.color = 0xF00FFF;
			_my.pic.transform.colorTransform = hit2;
		}
		if(_my.collision[CHARACTOR_COLLISION][0]){
			var hit31:ColorTransform = new ColorTransform();
			hit31.color = 0xFFF00F;
			_my.pic.transform.colorTransform = hit31;
		}
		else{
			var hit32:ColorTransform = new ColorTransform();
			hit32.color = 0xF00FFF;
			_my.pic.transform.colorTransform = hit32;
		}
	}

	public function Rotate(deg:uint):void{
		_my.vf.ViewRotation(deg,_my.size,_my.pic.x,_my.pic.y);
		_my.pic.x++;
	}
	
	public function set myAI(my:Charactor):void{
		_my = my;
	}

}

//視野座標用構造体
class ViewPoint {

	private var _p:Array;
	
	//視野は円の中心から下方に広がる三角形(時計回り)
	public function ViewPoint(view_size:int){
		_p = [  new Point(			   0,		 0),
				new Point(   view_size,2*view_size),
				new Point(-1*view_size,2*view_size)];
	}
	
	//視野のローカル座標をキャラの座標に合わせる
	public function ViewRefresh(pos:Point):void{
		_p[0].x += pos.x; _p[0].y += pos.y;
		_p[1].x += pos.x; _p[1].y += pos.y;
		_p[2].x += pos.x; _p[2].y += pos.y;

	}
	
	//視野の回転(キャラの向きの回転)
	public function ViewRotation(deg:Number,view_size:int,x:int,y:int):void{
		var pos:Point = new Point(x,y);
		var rad:Number = deg*Math.PI/180;
		
		//始点の_p[0]から_p[1],_p[2]へのベクトル
		var vp:Array = [new Point(0,0),
						new Point(_p[1].x - _p[0].x, _p[1].y - _p[0].y),
						new Point(_p[2].x - _p[0].x, _p[2].y - _p[0].y)];
		
		//回転後のベクトル座標
		_p[0] = new Point(vp[0].x*Math.cos(rad)-vp[0].y*Math.sin(rad), vp[0].x*Math.sin(rad)+vp[0].y*Math.cos(rad));
		_p[1] = new Point(vp[1].x*Math.cos(rad)-vp[1].y*Math.sin(rad), vp[1].x*Math.sin(rad)+vp[1].y*Math.cos(rad));
		_p[2] = new Point(vp[2].x*Math.cos(rad)-vp[2].y*Math.sin(rad), vp[2].x*Math.sin(rad)+vp[2].y*Math.cos(rad));
	}
	public function vpos(i:uint):Point{return (_p[i]);}
	public function spos(i:uint,p:Point):void{_p[i] = p;}
}

//補助計算関数
class MathPuls {

	//内積
	public static function VectorDot(a:Point,b:Point):int{
		return(a.x*b.x+a.y*b.y);
	}
	//外積
	public static function VectorCross(a:Point,b:Point):int{
		return(a.x*b.y-a.y*b.x);
	}
	//ベクトルの大きさ
	public static function VectorLength(a:Point):Number{
		return(Math.sqrt(a.x*a.x +a.y*a.y));
	}
	//2ベクトル間の距離
	public static function VectorDistance(a:Point,b:Point):Number{
		return(Math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
	}
}

//デバッグ用
class Debug extends Sprite{
	
	private var _tf:TextField;
	
	public function setText(txt:String):void{
		_tf.text = txt;
	}
	
	public function getText():TextField{
		return(_tf);
	}
	
	public function Debug(x:int,y:int){
		_tf = new TextField();
		_tf.text = "NULL";
		_tf.autoSize = "left"
		_tf.x = x;
		_tf.y = y;
	}
}