かつどんの活動記録#4-2 矩形同士の衝突判定の関数作成
<collision.h>
typedef struct Rectangle_TAG
{
VECTOR2 Pos; // 左上座標
VECTOR2 Size; // 幅と高さ
}RECTANGLE;
/* 矩形同士の当たり判定関数 */
bool Collision_IsHitRectangle(const RECTANGLE* pA, const RECTANGLE* pB);
<collision.cpp>
bool Collision_IsHitRectangle(const RECTANGLE* pA, const RECTANGLE* pB)
{
return ( pA->Pos.y + pA->Size.y > pB->Pos.y &&
pA->Pos.y < pB->Pos.y + pB->Size.y &&
pA->Pos.x + pA->Size.x > pB->Pos.x &&
pA->Pos.x < pB->Pos.x + pB->Size.x
);
}
受け取ったポインタ同士の衝突判定をし、当たっていたらtrueを返す関数です。
<collision.cpp>内の条件式を上から説明します。
例えばプレイヤーと四角ブロックの衝突判定だとしましょう。
プレイヤーの下端がブロックの上端よりも大きいかつ、
プレイヤーの上端がブロックの下端よりも小さいかつ、
プレイヤーの右端がブロックの左端よりも大きいかつ、
プレイヤーの左端がブロックの右端よりも小さい
となっています。
これで”当たっているかどうか”は判断できるのですが、ここで問題なのが”どの方向から当たっているか”が判断できません。
なので自分は下のようにして判断させました。
for (int i = 0; i < BLOCK_MAX; i++)
{
if (GetBlock_Pointer(i)->Enable == true)
{
// ブロック判定
if (Collision_IsHitRectangle(Player_GetRectangleCollision(), Block_GetRectangleCollision(i)))
{
if (Player_GetPointer()->oldPos.y + Player_GetPointer()->Size.y <= GetBlock_Pointer(i)->Pos.y)
{
// ブロックの上にプレイヤーがいる時の処理
}
else if (Player_GetPointer()->oldPos.y >= GetBlock_Pointer(i)->Pos.y + GetBlock_Pointer(i)->Size.y)
{
// ブロックの下にプレイヤーがいる時の処理
}
else if (Player_GetPointer()->oldPos.x + Player_GetPointer()->Size.x < GetBlock_Pointer(i)->Pos.x)
{
// ブロックの左にプレイヤーがいる時の処理
}
else if (Player_GetPointer()->oldPos.x > GetBlock_Pointer(i)->Pos.x + GetBlock_Pointer(i)->Size.x)
{
// ブロックの右にプレイヤーがいる時の処理
}
}
}
}
プレイヤーのoldPosっていうのは、プレイヤーの座標を更新する前に格納しておいた値です。
例えばブロックの上にプレイヤーがいる時というのは、
矩形同士が衝突していて、その瞬間のoldPosはブロックの上端より小さい値ですよね。(説明下手なんで下図参考になれば。。。)
同じように下、右、左も書いてあげればブロックとプレイヤーの当たり判定は完成です!