@flare-engine/input
Pointer / touch / gesture / virtual-control / gamepad / keyboard input. InputManager polls per frame; Pointer exposes the primary touch (the finger that started the current gesture) with isDown / justPressed / delta — other simultaneous touches reach only touches[], never pointer, and when the primary lifts it does not transfer to a remaining finger: pointer stays unset until every touch is up and a fresh press starts a new primary; GestureDetector emits tap / swipe / pinch / long-press; data-only VirtualJoystick + VirtualButton state (RN components live in @flare-engine/react); GamepadSource + RemapTable cover gamepad polling and persistent rebinds; createKeyboard provides buffered isDown / wasPressed / wasReleased edges per KeyboardEvent.code with blur-clears-held semantics.
Per-frame edge flags come in two deliberate shapes: per-thing boolean fields (Pointer.justPressed/justReleased, VirtualButtonState.justPressed/justReleased, GamepadButtonState.justPressed/justReleased) for state you already hold a reference to, and keyed query functions (KeyboardState.wasPressed/wasReleased(code), wasButtonPressed/wasButtonReleased(state, button)) for state addressed by an id.
Install
bun add @flare-engine/input
Usage
import {
InputManager,
GestureDetector,
createWebGamepadSource,
attachKeyboardListeners,
} from '@flare-engine/input';
const input = new InputManager();
const gestures = new GestureDetector();
gestures.onSwipe.add((e) => console.log(e.direction));
// Web: attach turnkey keyboard listener (mobile/RN: call input.keyboard.keyDown/keyUp directly)
attachKeyboardListeners(input.keyboard, window);
input.pollGamepads(createWebGamepadSource(navigator));
input.update(); // resets all per-frame edge flags including keyboard
Platform coverage
KeyboardState and KeyBindings are platform-neutral (mobile + web):
- Web —
attachKeyboardListeners(kb, window)is a turnkey DOM adapter that feedskeyDown/keyUpfrom native events and callskb.clear()onblur(stuck-key guard). It deliberately does NOT callpreventDefault— bare use lets Space/arrows scroll and Tab move DOM focus. For game-mode input, attach your own listener thatpreventDefaults game keys and forwardskb.keyDown(ev.code). - Mobile / RN — call
kb.keyDown(code)/kb.keyUp(code)directly from a hardware-keyboard native module or an on-screen source. The same edge semantics apply.
// Action binding example (platform-neutral)
import { InputManager, isActionDown, wasActionPressed, type KeyBindings } from '@flare-engine/input';
const bindings: KeyBindings = { jump: ['Space', 'KeyW'], fire: ['KeyZ', 'KeyJ'] };
function update(input: InputManager, player: { jump(): void; fire(): void }) {
// in update loop:
if (wasActionPressed(input.keyboard, bindings, 'jump')) player.jump();
if (isActionDown(input.keyboard, bindings, 'fire')) player.fire();
}
See API spec.
License
Apache-2.0