Skip to content
第06回 プレイヤーの被弾と無敵時間

3 / 4 敵弾および敵本体との接触判定 ​

このステップの目的

敵弾や敵本体がプレイヤーに接触したことを検知し、共通の被弾処理へ安全に接続します。

敵弾とプレイヤーの命中調停 ​

Game::ResolveCollisions()に、敵弾とプレイヤーの当たり判定を追加します。

Game.cppcpp
// 敵弾とプレイヤーの命中判定
for (EnemyShot& enemyShot : enemyShots.GetAll())
{
    if (!enemyShot.IsActive())
        continue;

    // プレイヤーの命中矩形と重なっているか判定
    if (!enemyShot.GetHitbox().Overlaps(player.GetHitbox()))
        continue;

    // 命中した敵弾を直ちに消滅させる
    enemyShot.Deactivate();

    // プレイヤーに被弾を依頼する
    if (player.TryTakeDamage())
    {
        // 被弾成立時の処理(後続回で効果音やエフェクトを追加する位置)
    }
}

無敵時間中でも敵弾を消滅させる理由 ​

player.TryTakeDamage()の結果にかかわらず、接触した敵弾を必ずenemyShot.Deactivate()で消す点に注目してください。

無敵時間中に敵弾を消さずに残すと、機体に重なったままになり、無敵時間が切れたときに連続して大きなダメージを受けます。接触した弾をすぐに消すと、公平で自然な動きになります。

敵本体とプレイヤーの接触判定 ​

シューティングゲームでは、敵の弾だけでなく敵の機体そのものに激突(体当たり)した際もダメージを受けます。
敵本体との接触も、敵弾とまったく同じPlayer::TryTakeDamage()を利用して調停します。

Game.cppcpp
// 敵本体とプレイヤーの接触判定
for (Enemy& enemy : enemies.GetAll())
{
    if (!enemy.IsActive())
        continue;

    if (!enemy.GetHitbox().Overlaps(player.GetHitbox()))
        continue;

    // 接触した敵を停止させる
    enemy.Deactivate();

    // プレイヤーにダメージを適用する
    player.TryTakeDamage();
}

接触した敵は、すぐにenemy.Deactivate()で停止させます。同じ敵と何度も接触判定が行われる不具合を防げます。

第04回の「プレイヤー弾と敵」に、今回の「敵弾とプレイヤー」「敵本体とプレイヤー」の2つのループを加えます。これで、オブジェクト間の相互作用をすべてGame::ResolveCollisions()で扱えます。

チェックリスト
  • 敵弾がプレイヤーに接触した瞬間に敵弾が消滅することを確認できる
  • 敵本体と接触した場合も敵が消滅し、プレイヤーに被弾処理が適用されることを確認できる
  • 無敵時間中に接触しても敵弾が消費され、無敵終了時の理不尽な連続ダメージが防がれている
  • 第04回の自機弾による敵撃破処理を維持したまま、被弾処理が正しく追加されている