MitiruEngine では UI は HTML / CSS / 少量の JS で書くのが基本方針です。C++ 側はゲームの数値を持ち、CEF に push するだけ。
- アクションの HP / スコア / コンボ
- RPG のメニュー (装備、アイテム、ステータス)
- RTS のミニマップ / ユニット情報 / 建設キュー
- シューティングのウェーブ情報 / ボムストック
- シミュレーションのパネル / トーストメッセージ
- ジャンル横断のダイアログ / 設定画面 / セーブスロット
どれも「HTML を書く + 値を流し込む」で同じ作り方になります。
HUD の最小構成
<!-- assets/hud.html -->
<div class="hud">
<div class="hud__hp">
<div class="hud__hp-bar" id="hp-bar" style="width: 100%"></div>
<span id="hp-label">100</span>
</div>
<div class="hud__score">SCORE <span id="score">0</span></div>
</div>
<script>
Mitiru.state.subscribe('stats.hp', hp => {
document.getElementById('hp-bar').style.width = hp + '%';
document.getElementById('hp-label').textContent = hp;
});
Mitiru.state.subscribe('stats.score', s => {
document.getElementById('score').textContent = s;
});
</script>
C++ 側はゲームのロジックで HP / スコアが変わったら CEF に通知します。
state.set("stats.hp", currentHp);
state.set("stats.score", currentScore);
ダイアログと選択肢
「背景 + キャラ + テキスト枠 + 選択肢」は CSS の図形だけで描けます。画像アセットが揃わない試作段階でも UI 全体を組めるのが CEF の強みです。
<div class="dialog">
<p class="dialog__name">Captain</p>
<p class="dialog__text">Target spotted, requesting orders.</p>
<ul class="dialog__choices">
<li><button onclick="choose(0)">Attack</button></li>
<li><button onclick="choose(1)">Hold position</button></li>
<li><button onclick="choose(2)">Withdraw</button></li>
</ul>
</div>
<script>
function choose(i) {
window.cefQuery({ request: 'dialog|choice:' + i });
}
</script>
C++ 側で選択結果を受け取って、シーンを進めます。
メニュー / トースト / モーダル
複雑な UI も同じ流儀です。CSS の position: fixed、backdrop-filter、transform を使えば、フローティングメニュー、トースト通知、フルスクリーンの設定画面まで自然に作れます。C++ 側は「メニューを開け」「閉じろ」のシグナルだけを送ります。
関連 API
mitiru::cef::StateStore— C++ ↔ JS のステート同期window.cefQuery— JS → C++ シグナル
もっと深く知る
- docs/BRIDGE_API_CONTRACT.md — bridge 仕様
- docs/HYBRID_RUNTIME.md — UI 専用レイヤとしての CEF