第03回 敵の出現と移動敵の移動計算の流れ
3 / 4 敵の移動処理の実装
このステップの目的
直進移動とサイン波を用いた波状移動の2種類の動きをEnemy::Update()に実装します。
敵の移動ロジックとパターンの切り替え
敵は共通して下方向へ進みます。出現時に渡されたBehaviourの値に応じて、移動パターンを切り替えます。
経過時間
Y座標を下方向へ進める
共通移動
共通移動
Behaviourを確認
挙動分岐
挙動分岐
X座標を維持
直進
挙動分岐
baseXを中心にsinで揺らす
波状移動
移動後の敵
画面下端を越えたら停止
Deactivate
基本となる下方向への直進移動
停止中の敵(!isActive)は更新処理を行いません。
有効な敵は、経過時間ageにdeltaTimeを加算し、Y座標に下方向の移動量を加えます。
Enemy.cppcpp
void Enemy::Update(float deltaTime)
{
if (!isActive)
return;
// 出現からの経過時間を加算する
age += deltaTime;
// 下方向(+Y方向)へ一定速度で前進する
position.y += moveSpeed * deltaTime;画面座標系では下が+Y方向であるため、下へ進めるには加算(+=)を行います。この作品のdeltaTimeは固定の1/60秒です。速度に掛けると1回分の移動量になり、毎秒60回更新できると指定した秒速で進みます。
画面下端での消滅判定
画面の最下部(tuning::ScreenHeight)を越えてプレイヤーの後方へ通り過ぎた敵は、Deactivate()を呼び出して停止状態にします。
Enemy.cppcpp
// 画面下端より外側へ出たら停止し、プールへ戻す
if (position.y > tuning::ScreenHeight)
Deactivate();停止したスロットは、次のEnemyManager::SpawnOne()の際に再び新しい敵として再利用されます。
サイン波(三角関数)による波状移動の実装
behaviourがBehaviour::Waveの敵には、下方向への進行に加えて左右への周期的な揺れ(振動)を追加します。
周期的な往復運動には、三角関数の
Enemy.cppcpp
// 波状移動の挙動であれば、sin関数を用いてX座標を左右に振動させる
if (behaviour == Behaviour::Wave)
{
float waveOffset = std::sin(age * tuning::enemy::WaveSpeed)
* tuning::enemy::WaveAmplitude;
position.x = baseX + waveOffset;
}サイン波計算の仕組み
-1.0から+1.0までの値を滑らかに往復します。
- 角度の進む速さ:
age * tuning::enemy::WaveSpeedstd::sinの角度はラジアンです。WaveSpeedは1秒あたりに進む角度を表し、角度が約6.28()進むと1往復します。値を2倍にすると、同じ時間に2倍の回数往復します。 - 揺れ幅(振幅):
* tuning::enemy::WaveAmplitude-1.0〜+1.0の値に振幅(ピクセル幅)を掛けることで、左右に揺れる距離(例えば左右に30ピクセルずつ)を決定します。 - 中心軸:
baseX + waveOffset
出現時の基準X座標baseXを中心として振動を加えることで、敵全体の隊列やレーン配置を保ったまま揺らすことができます。
三角関数を使うと、複雑な物理シミュレーションを組まずに、数行のコードで滑らかで自然な動きを表現できます。
チェックリスト
- 敵のY座標が下方向(+Y方向)へ滑らかに前進することを確認できる
- 直進する敵が基準レーンを崩さずにまっすぐ下降することを確認できる
- 波状移動の敵が
std::sin()によって左右に滑らかに揺れながら下降することを確認できる - 画面下端を越えた敵が
Deactivate()され、正常にプールへ戻ることを確認できる