MAC DEVのGame Demo Tutorial #3のソースを読んでみた。

まずはGameLayer(Layerを継承)のinitメソッド。背景と自機の生成と、chipmunkの初期化、自機のショットと敵(ただの岩)の生成をしてる。

//Add the background:
//背景をスプライトとして生成
Sprite *bg = [[Sprite spriteWithFile:@"bg.png"] retain];
//背景をセット。画像の中心座標を画面の中心に
bg.position = cpv(160,240);
//レイヤーにスプライトをセット(画面に表示される)
[self addChild: bg];

//Add the ship:
//自機のスプライトを生成
ship = [[Sprite spriteWithFile:@"ship.png"] retain];
//自機の座標、cocos2dでは座標の原点は左下
ship.position = cpv(50,50);
[self addChild: ship];
//今回自機は当たり判定つかないのでスプライトだけ登録してる
//当たり判定が必要なときはもうちょっと面倒な処理が必要

//Make it move:
//自機の挙動をスケジューラに登録
//定期的にmoveShipメソッドが呼ばれて自機が動く
[self schedule: @selector(moveShip:)];

//Make it shoot:
//画面タッチに対応するフラグ
//画面タッチするとショットが出る(タッチ処理は別のメソッド)
isTouchEnabled = YES;

//Initialize Chipmunk:
//chipmunkの初期化
cpInitChipmunk();

//chipmunk用の物理空間を作ってる・・・んだと思うよ?
space = cpSpaceNew();
//ここはまだちょっとわからないんだけど、
//当たり判定用に画面をグリッド分割しているものと思われ
//これに関しては後述
//ちなみにデフォルト値は第二引数(セルのサイズ?)100.0f
//第三引数(セルの最小個数?)1000
cpSpaceResizeStaticHash(space, 400.0f, 40);
cpSpaceResizeActiveHash(space, 100, 600);

//重力。y軸をマイナスにしてビルドすると岩が落下するのがわかる
//自機はただのスプライトなので重力の影響を受けません
space->gravity = cpv(0, 0);
//ここはわからん
space->elasticIterations = space->iterations;

//Update Chipmunk
//chipmunk用のスケジューラ登録
[self schedule: @selector(step:)];

//Bullet Manager, loads 10 bullets
//自機のショット生成
//自機が撃てるショットは10発。それをあらかじめ用意している
//ショットの詳しい挙動は別のメソッド
bullets = [[NSMutableArray alloc] init];
for(int i = 0; i < 10; i++)
{
	//ショットを生成、初期座標は画面外に設定
	Bullet *b = [[Bullet alloc] initWithCPBody:[self makeBulletX:-50 y:-50]];
	//配列に格納
	[bullets addObject: b];
	[b release];
}

//岩の生成
[self makeSpaceRockX:200 y:200];

以上でinitは終わり。スケジューラが二つあるのはchipmunk配下の岩とショット用に一つと、chipmunkとは無関係のただのスプライトな自機用に一つ。

コード中の当たり判定用の画面のグリッド分割だけど、これは以下のように利用されるのだと思われる。ホントかどうかは知らん。

サンプルコードのようにオブジェクト数が少ない場合はあまり関係ないけど、オブジェクト数が大量になった場合、その全てに対して当たり判定の処理をするととてつもない量の演算をしなくてはならなくなる。例えば弾100発と敵100体だったら、1フレーム当たり10000回の判定処理が発生することになる。これは現実的ではない。

なので、画面をグリッドに分けて同じグリッド内のオブジェクトに対してのみ当たり判定処理をすれば、当たり判定の演算回数を減らすことができるっていうパフォーマンスアップのためのチューニングを施しているのがこの関数(だと思う)。

じゃあグリッドを細かくすればするほど良いのかというとそうでもなくて、グリッドを跨ぐこともあるのでどのグリッドに属しているのかを判定するのにもそれなりに負荷がかかるからチューニングが必要なんだよ。ってことかと。

こういった当たり判定について詳しいサイトがあったんだけどURL失念したので、似たようなことが書かれている以下のサイトを参考に第7回 多対多の関係を賢く扱う

ってことで今回は終わり、次回に続きますよ。