Appearance
第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を実装します。
1 / 4プレイヤーの弾クラス弾1発分の機能を
PlayerShotクラスに実装する2 / 4PlayerShotManagerで弾を管理する弾を固定数の配列でまとめ、Gameクラスから独立した形で管理する3 / 4射撃入力と発射間隔射撃入力をゲーム内のアクションへ追加し、プレイヤーが弾を発射できるようにする4 / 4弾を更新して再利用する弾を毎フレーム更新して移動させ、画面外に出た弾をプールに戻して再利用する今回実装する範囲
| 区分 | 内容 |
|---|---|
| 新しく作る処理 | PlayerShot、PlayerShotManager、弾の画像ID、射撃入力 |
| プレイヤーへ追加する処理 | 発射間隔のタイマー、発射処理、発射位置 |
Gameへ追加する処理 | PlayerShotManagerの所有、生成、更新、描画、リセット |
| 後の回で扱う処理 | 敵との命中判定、攻撃力、エフェクト、発射音 |
今回の完成例
まず自分の実装を動かしてから、第03回の配布プロジェクトを完成例として比較します。
| 確認するファイル | 確認する内容 |
|---|---|
Player.cpp | 射撃入力、発射間隔、発射位置 |
PlayerShot.cpp | 1発分の生成、移動、停止、描画 |
PlayerShotManager.cpp | 固定配列の更新、描画、空き要素の再利用 |
Game.cpp | 弾の生成成功とPlayerShotManagerへの依頼 |