InputManager работает с действиями (семантическими именами), а не с кодами клавиш. Игра один раз задаёт маппинг — дальше везде только isActionActive / isActionJustPressed:
engine.input.bindActions({
advance: ['Space', 'Enter'],
menu: ['Escape'],
up: ['KeyW', 'ArrowUp'],
down: ['KeyS', 'ArrowDown'],
left: ['KeyA', 'ArrowLeft'],
right: ['KeyD', 'ArrowRight']
});
engine.input.isActionJustPressed('advance'); // нажато в этом тике
engine.input.isActionActive('up'); // зажато
engine.input.isActionJustReleased('attack'); // отпущено в этом тике (клавиши+геймпад)
Отпускание и удержание нужны для заряжаемых действий (замах, резонанс). Для точных кодов есть wasKeyPressed(code) / wasKeyReleased(code); у указателя — pointer.downTicks (сколько тиков удержана кнопка, 0 — только нажата).
Стандартная карта кнопок (0=A, 1=B, 8=Select, 9=Start, 12–15 — крестовина). Опрашивается автоматически в начале каждого тика (input.update() в Engine.tick):
engine.input.bindGamepad({
advance: [0], // A
menu: [9], // Start
up: [12], down: [13], left: [14], right: [15]
});
engine.input.getLeftStick(); // { x, y } в -1..1 (мёртвая зона 0.15) или null
Один и тот же код работает и с клавиатурой, и с геймпадом — действие единое.
Координаты указателя пересчитываются в виртуальные пиксели:
const p = engine.input.getPointer(); p.x, p.y; // виртуальные пиксели p.justPressed; // нажато в этом тике p.justReleased; // отпущено в этом тике p.down; // зажато p.isTouch; // это тач (для мобильного управления)
Для мобильных: джойстик появляется там, где игрок коснулся экрана. Добавляется в uiRoot сцены; опрашивается вектор:
import { VirtualJoystick } from '@rpg/engine';
const joystick = new VirtualJoystick({
screen: { width: 480, height: 270 },
radius: 28
});
engine.renderer.uiRoot.addChild(joystick);
// в update сцены:
const v = joystick.getVector(); // { x, y } в -1..1; {0,0} если не активен
player.moveBy(v.x * speed * dt, v.y * speed * dt);
Джойстик сам обрабатывает pointer-события (eventMode: 'static', hitArea на весь экран) и скрывает ввод «клик по миру», пока активен.
justPressed-флаги очищаются в input.endTick() — Engine вызывает его в конце каждого тика. Не вызывайте endTick вручную из сцены, иначе пропустите нажатия.
Используйте e.code-имена (KeyW, а не KeyЫ) — раскладка не важна. Для перенастраиваемых клавиш храните маппинг в Settings (extra) и вызывайте bindActions заново при изменении.