1 / 4 プレイヤー弾クラスの設計
提供済みのPlayerShotを読み、弾1発分の位置、有効フラグ、描画の役割を確認します。
提供済みの状態と責務を読む
このステップではPlayerShot.hとPlayerShot.cppの宣言・Spawn・Draw・GetDrawRectを読みます。これらは提供済みなので追加し直しません。未実装のUpdateはステップ4で編集します。
弾は発射位置から直進し、画面外へ出ると消滅します。この発射から消滅までの流れが、弾のライフサイクルです。
多数の弾を扱うための第一歩として、まずは「弾1発分」のデータと機能がひとつのクラスにどうまとまっているかを確認します。
PlayerShotクラスは、現在位置を表すpositionと、弾が画面上で動いているかを表す有効フラグisActiveを保持します。
#pragma once
#include "DxGame/Rect.h"
#include "DxGame/Vector2.h"
namespace dxgame::shooting
{
class ImageManager;
// プレイヤーが発射する1発の弾の位置と実行状態を管理する
class PlayerShot
{
public:
// 中心をstartPositionへ移動して弾を実行状態にする
void Spawn(const Vector2& startPosition);
// 弾を上方向へ移動し画面外へ出たら停止する
// deltaTimeは1フレームの経過秒数
void Update(float deltaTime);
// 実行中の弾を画像で描く
void Draw(const ImageManager& images) const;
// 更新、描画の対象ならtrueを返す
bool IsActive() const;
// 弾を更新、描画の対象外にする
void Deactivate();
// 表示用Rectを現在位置へ移動して返す
Rect GetDrawRect() const;
private:
// 弾の中心座標
Vector2 position = {};
bool isActive = false;
};
}弾の位置と有効状態はプライベート変数として保持します。外部からはSpawn()やDeactivate()を通して操作し、状態に矛盾が生じるのを防ぎます。
提供済みの発射と描画を追う
弾は、常に画面上に表示されているわけではありません。未発射の弾や、画面外へ飛び去った弾は停止状態(isActive == false)にしておく必要があります。
Spawn()が呼ばれると、指定された発射位置(銃口座標)をpositionに保存し、isActiveをtrueに設定して弾を有効化します。
void PlayerShot::Spawn(const Vector2& startPosition)
{
position = startPosition;
isActive = true;
}
bool PlayerShot::IsActive() const
{
return isActive;
}
void PlayerShot::Deactivate()
{
isActive = false;
}Draw()では、まずisActiveを確認します。停止中なら何も描かずに関数を終了し、有効な場合だけ画像を描きます。
void PlayerShot::Draw(const ImageManager& images) const
{
if (!isActive)
return;
Rect drawRect = GetDrawRect();
images.Draw(ImageManager::Id::PlayerShot, drawRect);
}弾の表示領域の計算
弾の画像サイズはGameTuning.hに定義されています。
機体と同様に、弾の中心座標から表示用の矩形を求めるGetDrawRect()の計算を読みます。
namespace playerShot
{
// 弾の中心を基準とした画像の表示範囲(幅10、高さ28)
inline constexpr Rect DrawRect = Rect::Centered(10.0f, 28.0f);
}Rect PlayerShot::GetDrawRect() const
{
return tuning::playerShot::DrawRect.MovedBy(position);
}これで「弾1発分」のデータ構造と描画機能を確認できました。
次のステップでは、このPlayerShotを複数束ねるPlayerShotManagerのうち、停止中の弾を探すSpawnを実装します。
-
PlayerShotクラスが位置座標positionと有効状態isActiveを保持している -
Spawn()によって初期位置が設定され、有効フラグがtrueになることを理解している - 停止中(
isActive == false)の弾は描画されないようガードされている - 中心座標から描画用の
Rectを正しく生成できている