Skip to content

第02回 プレイヤーの弾とオブジェクトプール

前回はプレイヤーを表示し、キー入力で操作できるようにしました。
今回は、プレイヤーの弾を題材に、複数のオブジェクトを管理する方法を学びます。

配布プロジェクト

前回の作業が完了した状態と同等のプロジェクトを配布します。

第02回のプロジェクトを展開し、ShootingGame2D.slnをVisual Studio 2026で開いてください。

配布ファイル一覧
ファイル役割
Source/Shooting/Game.cppゲームループとプレイヤーの呼び出し
Source/Shooting/Player.hプレイヤーの宣言
Source/Shooting/Player.cpp第01回で完成させた移動処理
Source/Shooting/ImageManager.h画像IDと描画機能
Assets/Images/Bullet.pngプレイヤー弾の画像

この回のゴール

今回の完成イメージ今回の完成イメージ
プレイヤーが弾を発射できるようになっている

ZキーまたはSpaceキーを押してプレイヤーから弾を連射できるようにします。
画面外へ出た弾は停止し、再利用できるようにします。

  • 弾1発分の位置、表示、実行状態をPlayerShotクラスにまとめる
  • PlayerShotManagerを通して複数の弾を管理する
  • 発射入力と発射間隔の制御をプレイヤーに追加する
  • 画面外へ出た弾を停止しプールの空きとして再利用することで、シューティングゲームの基本的な射撃のシステムを完成させる

今回のポイント

プレイヤーはゲーム中に一機だけなので、Gameが直接所有しても問題ありません。
一方、弾のように大量に存在するオブジェクトをGameが直接所有するのは無理があります。

強引な実装の例cpp
class Game
{
public:
    void Update(float deltaTime)
    {
        playerShot0.Update(deltaTime);
        playerShot1.Update(deltaTime);
        playerShot2.Update(deltaTime);
        playerShot3.Update(deltaTime);
        playerShot4.Update(deltaTime);
        playerShot5.Update(deltaTime);
    }
}

こうしたオブジェクトをまとめて扱うためには配列が便利です。

配列でまとめる例cpp

class Game
{
public:
    void Update(float deltaTime)
    {
        for (int i = 0; i < playerShots.size(); ++i)
            playerShots[i].Update(deltaTime);
    }

    void Draw() const
    {
        for (int i = 0; i < playerShots.size(); ++i)
            playerShots[i].Draw(images);
    }
private:
    // 6発分の弾の配列
    std::array<PlayerShot, 6> playerShots;
}

ですが、配列はあくまでデータ構造です。 同じ型のオブジェクトをまとめることはできますが、個々のオブジェクトの寿命や現在の状態に合わせた更新は、配列の外側で制御する必要があります。

ここまで複雑になると、弾の配列と操作する機能をまとめた弾の束を扱うクラスを用意するのが自然です。

今回は、弾の発射、停止、再利用の制御をまとめて扱うために管理クラスPlayerShotManagerを実装します。

今回実装する範囲

区分内容
新しく作る処理PlayerShotPlayerShotManager、弾の画像ID、射撃入力
プレイヤーへ追加する処理発射間隔のタイマー、発射処理、発射位置
Gameへ追加する処理PlayerShotManagerの所有、生成、更新、描画、リセット
後の回で扱う処理敵との命中判定、攻撃力、エフェクト、発射音

今回の完成例

まず自分の実装を動かしてから、第03回の配布プロジェクトを完成例として比較します。

確認するファイル確認する内容
Player.cpp射撃入力、発射間隔、発射位置
PlayerShot.cpp1発分の生成、移動、停止、描画
PlayerShotManager.cpp固定配列の更新、描画、空き要素の再利用
Game.cpp弾の生成成功とPlayerShotManagerへの依頼