あたり判定を管理
書き忘れましたが、私は当たり判定は矩形で管理するのが好きなので、矩形でやることにしますよ。
さて、とりあえず、1個のプレイヤーにN個の敵が接触したかを判定したいとします。そんな時は、敵キャラを動かす処理のところで矩形を登録しておき、プレイヤを動かす処理の部分で判定してやるのが一つの手です。
MainLoop { 敵判定リスト.reflesh(); // 判定を空にする // 敵を動かす foreach( 敵キャラ ) { 敵キャラ.Update(); 敵判定リスト.SetHantei(敵キャラの判定); } // 自機を動かす { 自機.Update(); if( 敵判定リスト.IsAtari(自機の判定) { //やられたー } } // 敵の表示 敵キャラ.Draw(); // 自機の表示 自機.Draw(); }
こんな感じすか。判定を登録するリストは、リスト的なものを適当に実装してやればOKです。が、登録はケツだけでOK、挿入削除無しってことなので、固定長配列に入れてしまうのが楽でしょう。
/* ただのRECT構造体ですが、後に拡張したいので、敢えて定義しておく typedef struct _tagAtariRect { int left; int top; int right; int bottom; }AtariRect; class CHanteiList { public: void SetHantei(AtariRect* pRect); int IsAtari(AtariRect* pRect); void Reflesh(); private: AtariRect mRect[1024]; // 1024個くらいでいいか? int pos; // 登録位置 };
こんな感じのクラスでいいですかね。つうことで実装。先ずはリストを空にするところから。
void CHanteiList::Reflesh() { pos = 0; }
実体をクリアしなくても、論理長を0にすればジューブン。続いて、判定の登録。
void CHanteiList::SetHantei(AtariRect* pRect) { memcpy( &(mRect[pos]), pRect, sizeof(AtariRect) ); pos++; }
バッファにコピーするだけー。スタックの実装みたいな感じですね。で、最後に判定
void CHanteiList::IsAtari(AtariRect* pRect) { int len = pos; for( int idx=0; idx<len; idx++ ) { AtariRect* pTarget = &(mRect[idx]); if( (pRect->left < pTarget->right) && (pRect->top < pTarget->bottom) && (pRect->right > pTarget->left) && (pRect->bottom > pTarget->top) ) { return 1; } } return 0; }
ループで回すだけっすね。登録されている敵の判定を順番に一巡り、自機の判定と比較して結果を出すってわけですね。
ってなわけで、次回はN個:N個の判定をやると思いたい