/**
* 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;
}
}