Appearance
第21回 敵の配置とジャンプ操作の改善
2 / 4 配置数に合わせて敵を管理する
このステップの目的
CSVの配置情報から敵を生成し、EnemyManager がまとめて描画します。
単体と集合の役割を分ける
Enemy は単体の位置と表示矩形を持ちます。EnemyManager はCSVから読み込んだ SpawnPoint の数だけ Enemy を保持します。第21回では配置と描画を扱い、巡回や活動状態は第22回で追加します。
EnemyManager.hcpp
#pragma once
#include <vector>
#include "Platformer/Enemy.h"
#include "Platformer/Stage.h"
namespace dxgame::platformer
{
class Camera;
class ImageManager;
// CSVから読み込んだ敵配置をEnemyの集合として所有する
class EnemyManager
{
public:
// ステージの配置情報から敵を作り直す
void Reset(const std::vector<SpawnPoint>& spawnPoints);
// カメラ内の敵を描画する
void Draw(const Camera& camera, const ImageManager& images) const;
std::size_t GetCount() const;
private:
std::vector<Enemy> enemies_;
};
}配置情報から初期化する
シューティングの弾では上限を事前に決めた std::array を使用しました。今回はCSVの配置数に合わせるため std::vector を使用します。std::vector は要素数を動的に変更できる配列です。Reset() で必要数を reserve() し、各配置へ初期化した Enemy を push_back() で追加します。
EnemyManager.cppcpp
void EnemyManager::Reset(const std::vector<SpawnPoint>& spawnPoints)
{
enemies_.clear();
enemies_.reserve(spawnPoints.size());
for (const SpawnPoint& spawnPoint : spawnPoints)
{
Enemy enemy;
enemy.Reset(spawnPoint.position);
enemies_.push_back(enemy);
}
}メモリの確保はステージ開始時の初期化でまとめて行います。毎フレームの描画時には要素を追加しません。
Gameへ接続する
Game.h で EnemyManager.h をインクルードし、enemies_ をメンバとして追加します。Game::ResetStage() へ enemies_.Reset(stage_.GetEnemySpawns()) を追加し、Game::Draw() から enemies_.Draw(camera_, images_) を呼び出します。
EnemyManager.cppcpp
void EnemyManager::Draw(const Camera& camera,
const ImageManager& images) const
{
for (const Enemy& enemy : enemies_)
enemy.Draw(camera, images);
}
std::size_t EnemyManager::GetCount() const
{
return enemies_.size();
}Enemy の宣言と定義をそろえてからビルドします。Enemy の画像IDと画像表は第13回から用意されているものを利用します。まずCSVに 90 を1つ追加し、敵が1体増えることを確認してください。
チェックリスト
- CSVの
90の配置数と、表示される敵の数が一致する - リセット時にCSVの位置へ敵が再配置される
-
std::arrayとstd::vectorを、要素数の決定方法に応じて使い分けられる