一般的に2Dのゲームでキャラクタ同士の当たり判定を検出する場合、長方形が用いられる。では、2つの長方形の重なり(衝突)のパターンにはどのようなものがあるだろうか。

これらのパターンをそれぞれ調べていたのでは面倒なので、上記3パターンを満たす簡単な判定方法を紹介する。

何度も説明しているが、キャラクタの位置情報は4つの頂点情報のX,Yで管理している。つまり、頂点情報のX,Y座標はそのまま長方形と考えられる。それを使って、当たり判定を行うプログラムを考える。
例えばキャラクタAの頂点情報がa、キャラクタBの頂点情報がbである場合、次のようなif文になる。
if ( a[0].x <= b[2].x && a[0].y <= b[2].y && a[2].x >= b[0].x && a[2].y >= b[0].y )
では実際に、2つのキャラクタのあたり判定を行うようプログラムを修正する。
当たり判定処理はいろんなところで使うことが想像されるので、関数化しておく。プロトタイプ宣言も行うこと。
//-----------------------------------------------------------------------------
// 関数名 : HitCheck()
// 機能概要: あたり判定関数
//-----------------------------------------------------------------------------
bool HitCheck(LPTLVERTEX v1, LPTLVERTEX v2)
{
if ( v1[0].x <= v2[2].x && v1[0].y <= v2[2].y && v1[2].x >= v2[0].x && v1[2].y >= v2[0].y )
return true;
else
return false;
}
この関数を使って、2つのキャラクタの衝突を調べてみる。例えば、衝突したらキャラクタ1が元の位置に戻るようにプログラムすると、次のようになる。
//-----------------------------------------------------------------------------
// 関数名 : StartFrame()
// 機能概要: スタート画面処理
//-----------------------------------------------------------------------------
void StartFrame(void)
{
float mx, my;
/* 描画処理 */
// キャラクタ1を描画
gl_lpD3ddev->SetTexture(0, gl_Texture1);
gl_lpD3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, VertexDataTbl1, sizeof(TLVERTX));
// キャラクタ2を描画
gl_lpD3ddev->SetTexture(0, gl_Texture2);
gl_lpD3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, VertexDataTbl2, sizeof(TLVERTX));
/* 移動処理 */
mx = my = 0.0f;
if ( gl_KeyTbl[VK_LEFT] & 0x80 ) mx = -2.0f;
if ( gl_KeyTbl[VK_UP] & 0x80 ) my = -2.0f;
if ( gl_KeyTbl[VK_RIGHT] & 0x80 ) mx = 2.0f;
if ( gl_KeyTbl[VK_DOWN] & 0x80 ) my = 2.0f;
Move(VertexDataTbl1, mx, my);
/* 指定範囲を超えないようにする */
MoveCheck(gl_rcMove, VertexDataTbl1);
/* 当たり判定 */
if ( HitCheck(VertexDataTbl1, VertexDataTbl2) )
InitVertex(VertexDataTbl1, 100.0f, 100.0f, 164.0f, 164.0f, 255);
// リターンキーが押されたら、ゲーム開始
if ( gl_KeyTbl[VK_RETURN] & 0x80) g_FrameNo = GAME_INIT;
}
※上記修正を行い、2つのキャラクタが衝突したら、キャラクタ1が元の場所に戻ることを確認する。
| BACK(画面からはみ出さないようにするには?) | NEXT(当たり判定を小さくするには?) |