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

1 / 4 プレイヤーの体力と被弾処理 ​

このステップの目的

プレイヤーのHPと無敵時間を管理し、被弾が成立したときだけ状態を変える処理を実装します。

HPと無敵時間をプレイヤー自身の状態として管理する ​

HPと無敵時間はグローバル変数にせず、プレイヤーのプライベート変数へまとめます。

Player.hcpp
public:
    // ダメージの適用を試み、実際にHPを減らせたらtrueを返す
    bool TryTakeDamage();

    // プレイヤーが生存しているか(HP > 0)を返す
    bool IsAlive() const;

    // 現在のHPを返す
    int GetHp() const;

private:
    int hp = 0;
    float invincibleTimer = 0.0f; // 無敵時間の残り秒数

IsAlive()はプレイヤーのHPが1以上残っているかどうかを返します。この関数は、次回のゲームオーバー判定などで利用します。

初期化と被弾可否の判定 ​

ゲーム開始時やリトライ時に呼ばれるPlayer::Reset()内で、HPと無敵時間を初期化します。

Player.cppcpp
void Player::Reset()
{
    position = tuning::player::StartPosition;
    shotTimer = 0.0f;
    invincibleTimer = 0.0f;
    hp = tuning::player::MaxHp;
}

初期HP(3)や無敵時間(1.5秒)の数値は、調整しやすいようにGameTuning.hに定義されています。

GameTuning.hcpp
namespace player
{
    inline constexpr int MaxHp = 3;
    inline constexpr float InvincibleTime = 1.5f;
}

TryTakeDamageの実装 ​

被弾処理を行うTryTakeDamage()では、まず無敵時間中であるかどうかを確認します。

Player.cppcpp
bool Player::TryTakeDamage()
{
    if (invincibleTimer > 0.0f)
        return false;

    --hp;
    invincibleTimer = tuning::player::InvincibleTime;
    return true;
}

bool Player::IsAlive() const
{
    return hp > 0;
}

int Player::GetHp() const
{
    return hp;
}

もしinvincibleTimerが0より大きい場合は、被弾を拒否して即座にfalseを返します。
無敵時間でない場合にのみ、hpを1減らし、タイマーを基準値(1.5秒)に設定してtrueを返します。

戻り値で被弾の成否を伝えると、呼び出し元のGameクラスで余分な条件判定をせずに済みます。

チェックリスト
  • HPと無敵時間がPlayerクラスのメンバ変数としてカプセル化されている
  • Player::Reset()でHPが最大値へ初期化され、無敵時間が0にリセットされる
  • 無敵時間中はTryTakeDamage()がfalseを返し、HPが減らないことを理解している
  • 被弾が成立した瞬間のみHPが1減少し、無敵タイマーが開始されることを説明できる