ここまでで、私たちはたくさんの部品を作ってきました。
でも一番大事なのはこれです。
どうやって全部をつなぐの?
今回はそれをやります。
難しくしません。
最小構成で「動く構造」を作ります。
1. まず全体像を見る
統合すると、こうなります。
requestAnimationFrame
↓
Game Loop
↓
update(dt)
↓
State / Scene
↓
render(alpha)
↓
Canvasさらに横から:
Input → Event → State変更つまり:
- 時間が進む
- 状態が変わる
- 描画される
- 入力で状態が変わる
これが一連の流れです。
2. 最小統合コード
まずは構造だけ。
class Game {
constructor() {
this.scene = new MainScene();
this.lastTime = 0;
this.accumulator = 0;
this.fixedDelta = 1000 / 60;
}
start() {
requestAnimationFrame(this.loop.bind(this));
}
loop(time) {
const delta = time - this.lastTime;
this.lastTime = time;
this.accumulator += delta;
while (this.accumulator >= this.fixedDelta) {
this.scene.update(this.fixedDelta);
this.accumulator -= this.fixedDelta;
}
const alpha = this.accumulator / this.fixedDelta;
this.scene.render(alpha);
requestAnimationFrame(this.loop.bind(this));
}
}3. Scene側
class MainScene {
constructor() {
this.x = 0;
this.prevX = 0;
this.speed = 100; // px per second
}
update(dt) {
this.prevX = this.x;
this.x += this.speed * (dt / 1000);
}
render(alpha) {
const interpolatedX =
this.prevX + (this.x - this.prevX) * alpha;
draw(interpolatedX);
}
}これで
全部がつながりました。
4. Input統合
window.addEventListener("click", () => {
game.scene.speed *= -1;
});これでクリックすると逆方向に動きます。
Input → State変更
という流れが完成です。
5. なぜこの構造が強いのか?
初心者の頃はこうなりがちです:
requestAnimationFrame(() => {
x += 2;
ctx.fillRect(x, 0, 50, 50);
});でもこれだと:
- フレームレート依存
- 状態と描画が混ざる
- 拡張できない
今回の構造は:
- 時間制御が安定
- 描画とロジック分離
- Scene追加可能
- Event拡張可能
つまり「育つ構造」です。
6. 統合後の最終アーキテクチャ
Game
├── Loop
├── SceneManager
│ └── Scene
│ ├── update()
│ └── render()
├── Input
└── EventBusこれが今回の到達点です。
ゲームっぽいですが、
UIでも、
インタラクティブWebでも、
可視化でも、
全部同じ構造です。
7. 実験:統合構造は本当に意味があるのか?
このデモでは、
- 上:Structured(Fixed Timestep + Interpolation)
- 下:Simple(Variable dt)
を 同時に比較できます。
両者には同じ dt が渡されています。
違いは「構造」だけです。
実験内容
① 通常状態で観察する
まずは何もせず動きを見てください。
- 上(緑)… Structured
- 下(赤)… Simple
普段はほとんど同じに見えます。
ここが重要です。
普段は差が出ない。
つまりこの構造は「保険」なのです。
② Heavy Load を ON にする
ボタンで Heavy Load を ON にしてください。
CPU負荷を疑似的に発生させます。
観察してください:
- Simple(赤)は揺れやすい
- Structured(緑)は安定しやすい
③ タブを切り替えて戻る(重要)
これが一番わかりやすい実験です。
- Heavy Load は ON のまま
- 別タブに移動
- 2〜3秒待つ
- 元のタブに戻る
👀 観察ポイント
🔴 Simple(下)
- 戻った瞬間に「ワープ」することがある
- dt が大きくなった分だけ一気に進む
- フレーム依存の影響が強い
理由:
x += speed * dt大きな dt がそのまま移動量になるため。
🟢 Structured(上)
- 大きな dt を分割して処理する
- 見た目が破綻しにくい
- Interpolation によって滑らか
理由:
while (accumulator >= fixedDelta)
update(fixedDelta)時間を小さく区切って消化するため。
🧠 この実験で見てほしいこと
普段は同じに見えます。
でも負荷がかかった瞬間に、
- Simple → 直接時間に振り回される
- Structured → 時間を管理する
という差が出ます。
🎯 本質
今回の違いは「テクニック」ではありません。
違いはこれです:
時間に従うか
時間を制御するか
これがアーキテクチャの差です。
8. 今回で完成したもの
あなたはもう:
- 60fpsの意味を理解し
- deltaTimeを理解し
- Fixed Time Stepを理解し
- Interpolationを理解し
- 状態管理を理解し
- Scene分離を理解し
- Event設計を理解し
- 統合構造を作った
これはもう初心者レベルではありません。
9. ここからどう進む?
ここから先は分岐します。
A. UI設計へ
- モーダル
- アニメーション設計
- 状態マシン
B. ゲームロジックへ
- 当たり判定
- 物理
- ECS
C. 可視化エンジンへ
- グラフ
- データアニメーション
- 時系列制御
どれも行けます。
10.まとめ
統合とは、
「全部を混ぜること」ではありません。
責務を分けたまま、接続すること。
これがアーキテクチャです。
今回でシリーズは一段落ですが、
本当のスタートはここからです。
🔎 このラボの全体像はこちら
→ UI Architecture Roadmap

コメントを残す