Newer
Older
rpg / docs / engine / input.md

Ввод: действия, клавиатура, мышь/тач, геймпад

Действия

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'); // отпущено в этом тике (клавиши+геймпад)

Одна клавиша может маппиться на несколько действий (например Space = advance в диалоге и attack вне его) — повторные bindActions не перезаписывают, а дополняют.

Отпускание и удержание нужны для заряжаемых действий (замах, резонанс). Для точных кодов есть 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 заново при изменении.