2Dアクション・テンプレート:地形ブロック対応
=前回までのあらすじ(更新があいたので)=
「Box2Dを使ったアクションゲームのテンプレートを作る」という目的のため、作業を続けてきた。
前回でようやく「物理エンジンの動作確認」まで行ったので、あとは
を行えば、だいたい完了する。(カメラなどの細かい設定も必要だが)
今回は「グラフィックと物理エンジンの同期」と「地形ブロックの作成」を行う
=グラフィックと物理エンジンの同期=
「コリジョン(ぶつかり判定)とグラフィックの位置を一致させる」という処理は、以下のような考えで行う。
「コリジョンの移動先を計算」という処理は、以前に出てきた
m_PhysWorld.Step(deltaTime, 10);
という処理のことなので、この後に「コリジョンの位置をもとにグラフィックの位置を求めてセットする」という処理を行えばいい。
問題は「コリジョンとグラフィックの対応関係をどう取るか」で、いくつかの方法があるが、ここでは「コリジョンのUserDataにグラフィック(厳密には後述のGameObject)をセットする」という方法を取る。こうすることで、以下のように位置の変更は書ける。
for(var b:b2Body = m_PhysWorld.GetBodyList(); b; b = b.GetNext()){ if(b.GetUserData()){ b.GetUserData().x = b.GetWorldCenter().x * PIXEL_PER_METER;//X座標 b.GetUserData().y = b.GetWorldCenter().y * PIXEL_PER_METER;//Y座標 b.GetUserData().rotation = b.GetAngle() * 360/(2.0*Math.PI);//回転 } }
上のコードでは、各コリジョン(b)に対し、そのUserData(=グラフィック)(左側)に、コリジョンの位置(をコンバートしたもの)(右側)をセットしている。
以上で「コリジョンとグラフィックの位置を一致させる」は実現できるが、後々のために「GameObject」というものを作成しておく。
=GameObjectの作成=
「コリジョンとグラフィックの位置を一致させる」という処理は「地形」だけに限らず、「プレイヤー」や「エネミー」や「弾」など複数のもので必要となる。そこで、これらをひとまとめに「GameObject」として扱い、その中で「コリジョンとグラフィックの一致」という処理を行うことにする。
といっても、基本的には「Imageを継承する」「コリジョンを保持する」というだけのことで、あとは「コリジョンの作成を簡単にできるように関数を追加」や「ついでに入力や位置のセットもできるようにしておく」という処理を追加しただけのものになる。(詳細は次回を参考のこと)
以降、「地形ブロック」や「プレイヤー」はこの「GameObject」を継承して作成することにする。
=地形ブロックの作成=
地形ブロックは以下のように書ける。
というか、こう書けるようにGameObjectなどを設計する。
package{ //mxml import mx.controls.*; public class CFloor extends IGameObject{ //パネルの幅のドット数 static public const PANEL_LEN:Number = 32.0;//dot //初期化処理 public function Init(i_X:Number, i_Y:Number):void{ //Pos { SetPos(i_X, i_Y); } //Image { var img:Image = ImageManager.LoadImage_Panel(); addChild(img); } //Collision { CreateCollision_Rect(PANEL_LEN, PANEL_LEN); } } } }
やっていることは、
- 外部から指定された位置に移動
- グラフィックをロード&セット
- コリジョンを作成(自動で同期)
の3つだけ。
「ImageManager.LoadImage_Panel()」の内容などは省略したが、「LoadImage_Player」などと同様に、グラフィックを返す処理になっている。
一応、床の作成まではできたが、GmaeObjectなどの説明が不足しているので、次回は「GameObjectの説明」を行い、その次に「プレイヤーの作成」を行う予定。