実践構築(統合)すべてをつなぐ「最小システムアーキテクチャ」

設計統合のアイキャッチ画像
← Prev Next →

ここまでで、私たちはたくさんの部品を作ってきました。

でも一番大事なのはこれです。

どうやって全部をつなぐの?

今回はそれをやります。

難しくしません。
最小構成で「動く構造」を作ります。

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(緑)は安定しやすい

③ タブを切り替えて戻る(重要)

これが一番わかりやすい実験です。

  1. Heavy Load は ON のまま
  2. 別タブに移動
  3. 2〜3秒待つ
  4. 元のタブに戻る

👀 観察ポイント

🔴 Simple(下)

  • 戻った瞬間に「ワープ」することがある
  • dt が大きくなった分だけ一気に進む
  • フレーム依存の影響が強い

理由:

x += speed * dt

大きな dt がそのまま移動量になるため。

🟢 Structured(上)

  • 大きな dt を分割して処理する
  • 見た目が破綻しにくい
  • Interpolation によって滑らか

理由:

while (accumulator >= fixedDelta)
  update(fixedDelta)

時間を小さく区切って消化するため。

🧠 この実験で見てほしいこと

普段は同じに見えます。

でも負荷がかかった瞬間に、

  • Simple → 直接時間に振り回される
  • Structured → 時間を管理する

という差が出ます。

🎯 本質

今回の違いは「テクニック」ではありません。

違いはこれです:

時間に従うか
時間を制御するか

これがアーキテクチャの差です。

8. 今回で完成したもの

あなたはもう:

これはもう初心者レベルではありません。

9. ここからどう進む?

ここから先は分岐します。

A. UI設計へ

  • モーダル
  • アニメーション設計
  • 状態マシン

B. ゲームロジックへ

  • 当たり判定
  • 物理
  • ECS

C. 可視化エンジンへ

  • グラフ
  • データアニメーション
  • 時系列制御

どれも行けます。

10.まとめ

統合とは、

「全部を混ぜること」ではありません。

責務を分けたまま、接続すること。

これがアーキテクチャです。

今回でシリーズは一段落ですが、
本当のスタートはここからです。

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

コメント

コメントを残す

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

CAPTCHA