Appearance
第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;
}
}チェックリスト
今回の変更箇所を指し示し、観察した結果とその理由を説明できますか。実験後の値とファイルを確認して次へ進みます。