Fixed Time Stepとは?フレームに左右されない時間制御の作り方

Fixed Time Stepのアイキャッチ画像

これまでの記事で、

を学んできました。

ここで出てくる疑問がこれです。

「フレームレートが変わったら、ゲームの速さも変わらない?」

実はその通りです。

1.なぜ問題が起きるの?

通常のループはこうなっています。

function loop(now) {
  const dt = (now - lastTime) / 1000;
  lastTime = now;

  update(dt);
  render();

  requestAnimationFrame(loop);
}

dt を使っているので一見問題なさそうですが…

❗ 問題点

  • 60fps → dt ≒ 0.016秒
  • 30fps → dt ≒ 0.033秒
  • 15fps → dt ≒ 0.066秒

フレームが落ちると 一気に大きく進む ことになります。

結果:

  • 当たり判定がすり抜ける
  • 物理が壊れる
  • 不安定な挙動になる

これを防ぐのが Fixed Time Step です。

2.Fixed Time Stepとは?

更新を「毎回同じ時間間隔」で進める方法です。

例えば:

1秒を 60回 に分ける
→ 1回 = 0.016666秒

つまり、

フレームが何fpsでも
updateは常に 1/60秒ずつ進める

という設計です。

3.イメージ

❌ 可変時間(Variable)

フレーム毎に進む距離がバラバラ

✅ 固定時間(Fixed)

常に同じ幅でカチカチ進む

4.実装してみよう(基本形)

const fixedDelta = 1 / 60; // 60回/秒
let accumulator = 0;
let lastTime = 0;

function loop(now) {
  const deltaTime = (now - lastTime) / 1000;
  lastTime = now;

  accumulator += deltaTime;

  while (accumulator >= fixedDelta) {
    update(fixedDelta);
    accumulator -= fixedDelta;
  }

  render();

  requestAnimationFrame(loop);
}

requestAnimationFrame(loop);

5.何をしているの?

accumulator(貯金箱)

時間を一旦ためる箱です。

例:

  • 今回のフレームで 0.033 秒進んだ
  • fixedDelta は 0.016 秒

→ 2回 update する

つまり、

遅れたらその分まとめて処理する

6.なぜ安定するの?

updateは常に:

1/60秒
1/60秒
1/60秒

と一定間隔で進みます。

フレームレートが落ちても、

  • 計算の粒度は一定
  • 物理計算が壊れない
  • 判定が安定する

7.注意:スパイラル・オブ・デス

もし処理が重すぎると、

遅れる
→ update回数が増える
→ さらに重くなる
→ さらに遅れる

という無限ループ状態になります。

Fixed Time Stepは安定した設計ですが、処理が追いつかなくなると「遅れを取り戻そうとしてさらに重くなる」危険があります。これをスパイラル・オブ・デスと呼びます。

対策:update回数を制限する

const maxUpdates = 5;
let updateCount = 0;

while (accumulator >= fixedDelta && updateCount < maxUpdates) {
  update(fixedDelta);
  accumulator -= fixedDelta;
  updateCount++;
}

どういう意味?

「1フレームで最大5回までしかupdateしない」

つまり:

取り戻せない遅れは捨てる

という考え方。

8.実験:フレーム落ちで壊れるのはどっち?

  • 左:Variable Time
  • 右:Fixed Time
  • Heavy LoadボタンでCPU負荷追加

観察ポイント

  1. Heavy Load OFF → ほぼ同じ動き
  2. Heavy Load ON →
    • Variableはガタつく
    • Fixedは安定

9.まとめ

VariableFixed
実装簡単少し複雑
安定性不安定安定
物理向き×
ゲーム向き

10.次に進むなら

Fixed Time Stepで安定したら次はこれ:

👉 #10 状態管理統合
updateとrenderをどこに置くのか?

🔎 このラボの全体像はこちら
UI Architecture Roadmap

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA