第03回 敵の出現と移動
2 / 4 敵の出現制御とレーン分割
このステップの目的
出現タイマーとレーン分割を使い、画面上端から規則的に敵を出現させながら、動きに変化をつけます。
敵の出現アルゴリズム
敵の出現間隔と出現位置は、難易度やゲームのテンポを決める重要な要素です。
この作品では、画面の横幅を均等に分けたレーンを用意します。タイマーが0になるたびに敵を1体出し、次のレーンへ進みます。端まで進んだら最初のレーンへ戻り、この順序を繰り返します。
出現パラメータの外部定義
敵の出現間隔やレーンの間隔は、ゲームバランスを調整しながら何度も変更する値です。
コード内に数値を直接書くハードコードを避け、GameTuning.hに定義します。
GameTuning.hcpp
namespace enemy
{
// 出現レーンの設定
inline constexpr int LaneCount = 8; // レーンの総数(8分割)
inline constexpr float LaneStart = 64.0f; // 最も左側のレーンのX座標
inline constexpr float LaneSpacing = 72.0f; // レーン間の距離
// 出現間隔(秒)
inline constexpr float SpawnInterval = 0.6f;
// 速度とパターンの変化ルール
inline constexpr int SpeedLevels = 3;
inline constexpr float BaseSpeed = 120.0f;
inline constexpr float SpeedStep = 20.0f;
inline constexpr int WaveInterval = 4; // 4体に1体の割合で波状移動にする
}調整値をまとめておくと、レーン数や出現間隔を変更しやすくなります。
出現タイマーによる周期管理
EnemyManager::Update()では、まず現在有効なすべての敵の移動を更新し、続いて出現タイマーを減算します。
EnemyManager.cppcpp
void EnemyManager::Update(float deltaTime)
{
for (Enemy& enemy : enemies)
enemy.Update(deltaTime);
spawnTimer -= deltaTime;
if (spawnTimer <= 0.0f)
{
SpawnOne();
spawnTimer = tuning::enemy::SpawnInterval;
}
}タイマーが0以下になったらSpawnOne()を呼び出して敵を1体出現させ、タイマーを基準値(SpawnInterval)に再設定します。
レーン計算と敵パラメータの決定
敵を1体出現させるSpawnOne()では、停止中の敵スロットを探し、出現番号(spawnIndex)に基づいて出現位置、移動速度、移動パターンを算出します。
EnemyManager.cppcpp
void EnemyManager::SpawnOne()
{
// spawnIndexから出現レーン、速度、移動方法を順番に決める
for (Enemy& enemy : enemies)
{
if (enemy.IsActive())
continue;
int speedLevel = spawnIndex % tuning::enemy::SpeedLevels;
float speed = tuning::enemy::BaseSpeed + speedLevel * tuning::enemy::SpeedStep;
int lane = spawnIndex % tuning::enemy::LaneCount;
Vector2 startPosition =
{
tuning::enemy::LaneStart + lane * tuning::enemy::LaneSpacing,
0.0f
};
Enemy::Behaviour pattern =
(spawnIndex + 1) % tuning::enemy::WaveInterval == 0
? Enemy::Behaviour::Wave
: Enemy::Behaviour::Straight;
enemy.Spawn(startPosition, speed, pattern);
++spawnIndex;
return;
}
}剰余演算子(%)による規則的な変化
spawnIndexは、敵が出現するたびに1増える通算カウンタです。
剰余演算子%で割った余りを使い、次のように規則的な変化をつけます。
- レーンの循環:
spawnIndex % 8により、出現位置は0〜7のレーンを順番にループします。 - 速度の段階変化:
spawnIndex % 3により、速度が3段階(120、140、160ピクセル/秒)で周期的に切り替わります。 - 移動タイプの切り替え:
(spawnIndex + 1) % 4 == 0により、4回に1回の頻度で直進から波状移動(Wave)へと変化します。
プールが満杯で空きがなければ、何もせずに関数を終了します。この場合もタイマーで次の出現まで待ちます。上限を超えて生成せず、クラッシュを防ぎます。
チェックリスト
-
LaneStartとLaneSpacingを用いて等間隔なレーン座標が計算されている - 出現タイマーによって一定周期で
SpawnOne()が呼び出されている - 剰余演算子を用いて、出現レーン、移動速度、移動パターンに規則的な変化がつけられている
- プール内の停止中の敵スロットのみを再利用して出現させている