Skip to content
第25回 個体の生成と共通の前進

2 / 2 秒単位の前進 ​

このステップの目的

移動速度と経過秒数から移動量を求めます。

移動量を予想する ​

移動速度70単位/秒で1/60秒進むと、移動量は約1.17単位です。60回更新した場合は何単位進むか、実行前に予想してください。

前進処理を実装する ​

Battle.cppのBattle::MoveUnitsの仮の本体を置き換えます。units_を参照で列挙し、data_.units[unit.definition]から性能を取ります。相手までの距離を返すFindTargetは、今は拠点だけを返す提供関数です。

移動速度 × dtを移動量とし、味方には加算、敵には減算します。拠点までの距離から射程を引いた値より先へ進めないよう、std::minで小さい方を選んでください。負の移動量はstd::max(0.0, ...)で0にします。参照で列挙すると、個体のコピーではなく戦場の位置を更新できます。

表示用の時計と点滅時間は参考コードの先頭にある3行を用意してください。現在は静止姿を表示しますが、後で表示を切り替えるときにも同じ時計を使います。動いたらMotion::Move、止まったらMotion::Idleを記録します。

生成と移動を接続した後、1を押します。味方が右へ進み、敵拠点の手前で止まれば成功です。まだ攻撃と勝敗は実装していません。

速度を変える ​

LessonData.cppの軽装兵の速度70を35に変更してビルドし、同じ距離に到達する時間を比べます。確認後は70へ戻し、この回の到達状態を次へ引き継ぎます。

実装後に比較する参考コード
Source/TowerDefense/Battle.cppcpp
void Battle::MoveUnits(double dt)
{
    for (auto& unit : units_)
    {
        unit.animationSec += dt;
        unit.attackDisplaySec = std::max(0.0, unit.attackDisplaySec - dt);
        unit.hitDisplaySec = std::max(0.0, unit.hitDisplaySec - dt);
        const auto& type = data_.units[unit.definition];
        const double remaining = FindTarget(unit).distance - type.attackRange;
        const double move = std::max(0.0, std::min(type.moveSpeed * dt, remaining));
        unit.x += (unit.team == Team::Ally ? 1 : -1) * move;
        unit.motion = move > 0 ? Motion::Move : Motion::Idle;
        if (unit.attackDisplaySec > 0) unit.motion = Motion::Attack;
    }
}
チェックリスト

今回の変更箇所を指し示し、観察した結果とその理由を説明できますか。実験後の値とファイルを確認して次へ進みます。

ゲームプログラミング実践