まず「矩形(くけい)」とは四角形の事です。
「円」の衝突判定は比較的簡単なため、色々な場面で使用されますが「円」だけでは対処出来ない事も多くあります。
例えば四角い物体同士の衝突判定を「円」で行うと、
この状態でも2つの物体は衝突していない事になります。
また長細い物体の衝突判定を「円」で行うと、
複数の「円」が必要になります。
では「矩形」の衝突判定はどのように考えればよいでしょうか。
衝突している状態と、衝突していない状態を図にしてみます。
1と3は衝突しておらず、2と4は衝突してる状態です。
注目して欲しいのは辺の状態です。
とりあえず、左右方向だけを考え注目して欲しい辺の色を変えてみます。
1と2は「物体Aの右辺」と「物体Bの左辺」に注目しました。
3と4は「物体Aの左辺」と「物体Bの右辺」に注目しています。
これを見て考えると、
「物体Aの右辺」が「物体Bの左辺」より「右にある」時
「物体Aの左辺」が「物体Bの右辺」より「左にある」時
2つの物体は衝突している、と判断出来そうです。
ただし、これは左右方向だけですから、同じことを上下方向でも考えなければなりません。
上下方向を考えると、
「物体Aの底辺」が「物体Bの上辺」より「下にある」時
「物体Aの上辺」が「物体Bの底辺」より「上にある」時
2つの物体は衝突している、と判断出来ます。
左右と上下の条件が全て整った時に、2つの物体は衝突しています。
プログラムにするため言葉を座標に置き換えてみましょう。
現在のプログラムで使っている情報は「転送先XY座標」と「幅」「高さ」です。
「物体Aの右辺」が「物体Bの左辺」より「右にある」時
は
「物体AのX座標+幅」が「物体BのX座標」より「大きい」時
と書き換える事が出来ます。
クライアント領域の座標の原点は左上ですから「右にある」と言うのは、座標として「大きい」と言う事です。
残りの3つも変えてみます。
「物体Aの左辺」が「物体Bの右辺」より「左にある」時
は
「物体AのX座標」が「物体BのX座標+幅」より「小さい」時
となり、
「物体Aの底辺」が「物体Bの上辺」より「下にある」時
は
「物体AのY座標+高さ」が「物体BのY座標」より「大きい」時
となり、
「物体Aの上辺」が「物体Bの底辺」より「上にある」時
は
「物体AのY座標」が「物体BのY座標+高さ」より「小さい」時
となります。
この4つの条件、
「物体AのX座標+幅」が「物体BのX座標」より「大きい」時
「物体AのX座標」が「物体BのX座標+幅」より「小さい」時
「物体AのY座標+高さ」が「物体BのY座標」より「大きい」時
「物体AのY座標」が「物体BのY座標+高さ」より「小さい」時
が、全て成り立つ時、2つの物体は衝突したと言う事になります。
それでは「Base.h」を開き、関数のプロトタイプ宣言を追加しましょう。
class Base {
public:
Base(const int width, const int height);
bool CollideCircle(const Base &refTarget);
bool CollideBox(const Base &refTarget);
void Delete();
|
「Base.cpp」を開き、「CollideCircle関数」の下に実体を追加します。
bool Base::CollideBox(const Base &refTarget) { if (!m_bExist) { return false; } if (!refTarget.m_bExist) { return false; } if (m_x + WIDTH > refTarget.m_x && m_x < refTarget.m_x + refTarget.WIDTH && m_y + HEIGHT > refTarget.m_y && m_y < refTarget.m_y + refTarget.HEIGHT) { return true; } return false; } |
上に書いてある4つの条件と見比べてください。
次に「SceneGame.cpp」の「Update関数」の衝突判定関数を差し替えてください。
void SceneGame::Update()
{
if (m_shot.CollideBox(m_enemy)) {
m_enemy.Delete();
m_shot.Delete();
}
m_player.Update(m_pEngine, m_shot);
m_shot.Update();
m_enemy.Update();
}
|
それでは実行してみましょう。
ちゃんと「弾」が当たって「敵」が消えれば成功です。
「円」と同じように、判定の範囲を狭める事も出来ますが説明は省略します。
要は判定に使う「矩形」を小さくすれば良いだけです。
「円」と「矩形」2つの衝突判定方法を説明しましたが、単純なゲームであればこの2つの方法である程度はカバー出来ると思います。
その他の判定については、別の項目で説明したいと思います。