第4部 演習 — ゲームプログラミングパターン¶
問1. 概念確認¶
正誤を判定し、誤りは訂正してください。
- Event QueueはObserverと違い、発行者と購読者の「時間的結合」を切る。
- ECSはComponentパターンの改良版であり、常に上位互換である。
- Object Poolは使わない間もメモリを占有する。
- Behavior Treeは毎フレーム根から評価するため、遷移を書かなくても優先度の割り込みが起きる。
- Service LocatorはDIと違い、依存がクラスのシグネチャに現れる。
解答
1. **正**([Event Queue](event_queue_and_pubsub.md))。2. **誤**。動機が別(柔軟性vs性能)で、少数の複雑なオブジェクトにはComponentが向く([Component と ECS](component_and_ecs.md))。3. **正**。それがプールの代償([Object Pool](object_pool.md))。4. **正**([Behavior Tree](behavior_tree_and_blackboard.md))。5. **誤**。逆。シグネチャに現れるのはDI([Service LocatorとDI](service_locator_and_di.md))。問2. コード読解¶
while (accumulator >= kFixedDt) { FixedUpdate(kFixedDt); accumulator -= kFixedDt; }
Render(accumulator / kFixedDt);
Renderの引数は何のために使いますか。- このループに上限を付けないと何が起きますか。
解答
1. 補間係数。固定更新の「間」の時刻での見た目を、前回と今回の状態の補間で描き、カクつきを防ぐ。2. 更新1回に1/60秒以上かかるマシンでaccumulatorが増え続け、消化しようとするほど遅くなる「死のスパイラル」([Game Loop](game_loop_and_update.md))。問3. 問題のあるコードの改善¶
「被弾のたびに Instantiate(damagePopupPrefab)、表示終了で Destroy。連続ヒットするとフレーム落ちし、GCスパイクも出る」— 適用すべきパターンと実装上の注意点2つ(状態リセット/参照の無効化)を説明してください。
解答の要点
[Object Pool](object_pool.md)。注意点: (1) 再利用時のリセット漏れ(前の表示テキスト・アニメ進行が残る)→ Acquire時に完全初期化。(2) 貸出先が持つ参照のstale化 → 表示終了は必ずプール経由で返し、外部が長期保持しない設計に(必要なら世代ハンドル)。加えてUnityなら`SetActive`切替とCanvas再構築コストにも注意。問4. 設計比較¶
「敵AI(雑魚30種、ボス3種)」に (a) enum+switchのFSM、(b) Stateパターン、(c) Behavior Tree を検討します。「雑魚は3状態で共通、ボスは10種類以上の行動と優先度割り込みあり」という条件で構成を提案してください。
解答の要点
雑魚: 共通の3状態FSM(enum+switch)を1つ書き、パラメータ([Type Object](type_object_and_sandbox.md))で個性を出す——30種にクラス階層やBTは過剰。ボス: [BT](behavior_tree_and_blackboard.md)(優先度と割り込みの仕様に一致)+実行中の動作は小さなFSM。**「全部同じ仕組みに統一」しないのが正解**という点が本問の狙い。問5. デバッグ問題¶
Pub/Subバス導入後、「アイテム取得イベントで所持数UIが更新されるはずが、たまに1個ズレる」報告。調査手順を3ステップで書いてください。
解答の要点
(1) イベントに積んだ値の確認: 発行時に「取得後の総数」ではなく「取得数」を積み、購読側が古い状態と合算していないか(遅延配送では**必要な値を全部積む**鉄則 → [Event Queue](event_queue_and_pubsub.md))。(2) 二重購読の確認: 画面の開閉で購読が重複していないか([Observer](../03_design_patterns/observer.md)の多重実行)。(3) 配送タイミングの確認: UI更新がイベント処理より先に走るフレーム順序になっていないか。——「バスは追跡性が最悪」という欠点への実践的回答として、イベントログ(全発行の記録)を最初に仕込むのも正解。問6. 説明問題¶
「StateとStrategyって同じ構造ですよね? なぜ別の名前なんですか?」への回答を3文以内で書いてください。
解答例
構造(振る舞いオブジェクトへの委譲)は同じで、違いは**変わり方の意味**にある。Stateは「時間とともに自分で遷移する状況」を表し、状態自身が次の状態を決める。Strategyは「外部から与えられたやり方」で、装着後は自分では変わらない——だから設計意図を伝える名前が分かれている([ステートマシン](state_machines.md))。問7. 小規模実装問題¶
以下から1つ選んで実装してください(いずれもsamples/に出発点あり)。
- samples/event_queue.cpp: SE再生要求の同フレーム重複除去を追加
- samples/behavior_tree.cpp: 「逃げる」最優先枝の追加
- samples/object_pool.cpp: 世代付きハンドルの追加
- samples/fsm_guard.cpp: Search状態の追加