2Dアクション・テンプレート:GameObject

=GameObjectのコード=

GameObjectのコードを先に載せておく。

package{
  //mxml
  import mx.core.*;
  import mx.containers.*;
  import mx.controls.*;

  public class IGameObject extends Image{

    //------------------
    //Var
    //------------------

    //==GameObject==

    //GameObjectListを形成するためのポインタ
    public var m_NextObj:IGameObject;
    public var m_PrevObj:IGameObject;

    //リストから外れるためのフラグ
    public var m_KillFlag:Boolean = false;

    //==Collision==

    //Collision
    protected var m_Collision:Collision;

    //==Input==

    //Input
    protected var m_Input:IInput;


    //------------------
    //Function
    //------------------


    //==GameObject==

    //Update:オーバライドして使う
    public function Update(i_DeltaTime:Number):void{
    }

    //削除される時に呼ばれる処理:オーバライドして使う
    public function OnDestroy():void{
    }


    //==Coordinate==

    //Pos
    protected function SetPos(i_X:Number, i_Y:Number):void{
      this.x = i_X;
      this.y = i_Y;

      if(m_Collision != null){
        m_Collision.SetPos(i_X, i_Y);
      }
    }


    //==Collision==

    //-Rect
    protected function CreateCollision_Rect(i_W:Number, i_H:Number):void{
      m_Collision = CollisionManager.CreateCollision_Rect(i_W, i_H);
      m_Collision.SyncObject(this);

      m_Collision.SetPos(this.x, this.y);
    }

    //-Circle
    protected function CreateCollision_Circle(i_Rad:Number):void{
      m_Collision = CollisionManager.CreateCollision_Circle(i_Rad);
      m_Collision.SyncObject(this);

      m_Collision.SetPos(this.x, this.y);
    }


    //==Input==

    //Input
    public function SetInput(i_Input:IInput):void{
      m_Input = i_Input;
    }
  }
}


あと、GameObjectを管理するGameObjectManagerも。

//author Show=O=Healer
package{
  public class GameObjectManager{

    //リストの先頭
    static private var m_ObjectList:IGameObject;

    //Box2Dとほぼ同様にObjectを管理する
    //-Add
    static public function Register(i_Obj:IGameObject):void{
      if(m_ObjectList != null){
        m_ObjectList.m_PrevObj = i_Obj;
      }

      m_ObjectList = i_Obj;
    }
    //-Del
    static public function Remove(i_Obj:IGameObject):void{
      if(i_Obj.m_PrevObj != null){
        i_Obj.m_PrevObj.m_NextObj = i_Obj.m_NextObj;
      }
      if(i_Obj.m_NextObj != null){
        i_Obj.m_NextObj.m_PrevObj = i_Obj.m_PrevObj;
      }
      if(i_Obj == m_ObjectList){
        m_ObjectList = i_Obj.m_NextObj;
      }
    }

    //#Update
    static public function Update(i_DeltaTime:Number):void{
      var obj:IGameObject;

      //各GameObjectのUpdate
      obj = m_ObjectList;
      while(obj){
        obj.Update(i_DeltaTime);

        obj = obj.m_NextObj;
      }

      //Killが呼ばれたものは削除する
      obj = m_ObjectList;
      while(obj){
        if(obj.m_KillFlag){
          obj.OnDestroy();
          obj = obj.m_NextObj;
          Remove(obj);
        }else{
          obj = obj.m_NextObj;
        }
      }
    }

  }
}

=コード解説=

GameObjectでやっていることは、主に以下の3つ。

  • コリジョン(Collision)の操作
  • 入力(Input)の保持
  • 管理がしやすいようにリスト化に対応


コリジョンのための「Collision」や「CollisionManager」はまた別のクラスとして作ってあり、GameObjectでは「コリジョンの作成」「UserDataに自分をセット」「初期位置の指定」を行っている。


「Input」はそのまま保持&外部からセットできるようにしてあるだけで、GameObjectではそれ以上のことはしていない。


「全てのGameObjectのUpdateを毎回呼ぶ」ために、GameObjectを「リスト」として扱えるようにしている。リストの先頭をGameObjectManagerで持っておき、あとは「m_NextObj」を辿っていけば、全てのGameObjectをゲットできる仕組み。(Box2Dと同じ)
また、「やられた敵は消える」「弾が当たったら弾は消える」などの「消える処理」のために、「KillFlag」を立てたらリストから削除できるようにしておく。(まだ動作確認をしていないので、間違えてるかもしれない)


GameObjectの構造はだいたい以上の通り。次回は「プレイヤーの作成」の予定。