第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減少し、無敵タイマーが開始されることを説明できる