入力はゲームの種類で形が変わります。アクションは毎フレームのキー押下、RPG はキー単発と UI クリック、RTS はドラッグとモディファイア、シミュレーションはパネル操作 ── どれも MitiruEngine では「C++ 側で意味を決める、CEF 側は発火するだけ」が基本です。
具体的には:
- キーボード / マウス / ゲームパッドの raw 入力 は C++ 側で受けて
InputMapperで「Action (例: Jump, Fire, ConfirmMenu)」に変換する - HTML 上のボタンや UI クリック は CEF 側で
window.cefQuery(...)を呼んで C++ に「何が起きたか」を通知する - C++ 側は
BridgeActionRouterで受けて、シーンの状態を更新する
JS 側にゲームロジックを書かないので、入力の解釈はどんなジャンルでも 1 か所 (C++) にまとまります。
C++ で Action に束ねる
#include <mitiru/input/InputMapper.hpp>
#include <mitiru/input/BridgeActionRouter.hpp>
enum class Action { MoveLeft, MoveRight, Fire, Pause };
mitiru::input::InputMapper<Action> mapper;
mapper.bindKey(Action::MoveLeft, mitiru::input::Key::A);
mapper.bindKey(Action::MoveRight, mitiru::input::Key::D);
mapper.bindKey(Action::Fire, mitiru::input::Key::Space);
mapper.bindKey(Action::Pause, mitiru::input::Key::Escape);
void update(float dt) {
if (mapper.isDown(Action::MoveLeft)) player.x -= speed * dt;
if (mapper.isDown(Action::MoveRight)) player.x += speed * dt;
if (mapper.wasPressed(Action::Fire)) spawnBullet();
if (mapper.wasPressed(Action::Pause)) pushScene<PauseScene>();
}
シューティングなら isDown で連射、RTS の単発コマンドなら wasPressed で一度だけ反応、と使い分けます。
CEF 側から C++ にイベントを送る
HUD のボタンや確認ダイアログのクリックは HTML 上に置きます。発火だけ C++ に送って、状態の更新は C++ 側で処理します。
<button id="btn-pause">Pause</button>
<script>
document.getElementById('btn-pause').addEventListener('click', () => {
// signal-only bridge: 「何が起きたか」だけ通知する
window.cefQuery({ request: 'ui|pause-pressed' });
});
</script>
C++ 側はハンドラを登録するだけ。
engine.cefContext().registerHandler("ui", [&](const std::string& payload) {
if (payload == "pause-pressed") game.requestPause();
return std::string{"ok"};
});
ランタイムランドラを使う
web/mitiru_runtime/mitiru_input.js は、キー入力 / マウス位置 / ボタン状態を C++ 側に簡単に流すための薄いラッパです。アクション系のように HTML 上で UI を出しつつ C++ がメインの入力を持つ構成で便利です。
関連 API
mitiru::input::InputMapper— Action 抽象化mitiru::input::BridgeActionRouter— CEF → C++ ルーティングmitiru::input::BridgeInputAdapter— Bridge イベントを Input に変換
もっと深く知る
- docs/BRIDGE_API_CONTRACT.md — JS ↔ C++ メッセージ仕様
- アーキテクチャ — Bridge は signal-only という設計判断