Input Handling
Estella provides input handling through the Input resource. The InputPlugin is registered by the engine automatically, binding DOM keyboard, mouse, touch, and scroll events.
Using Input in Systems
Access input state through the Res(Input) system parameter:
import { defineSystem, addSystem, Res, Input, Query, Mut, Transform } from 'esengine';
addSystem(defineSystem( [Res(Input), Query(Mut(Transform))], (input, query) => { for (const [entity, transform] of query) { if (input.isKeyDown('KeyW')) { transform.position.y -= 5; } if (input.isKeyDown('KeyS')) { transform.position.y += 5; } if (input.isKeyDown('KeyA')) { transform.position.x -= 5; } if (input.isKeyDown('KeyD')) { transform.position.x += 5; } } }));Keyboard Input
Key State
// Currently held down (true every frame while held)if (input.isKeyDown('Space')) { charge();}
// Just pressed this frame (true for one frame only)if (input.isKeyPressed('Space')) { jump();}
// Just released this frame (true for one frame only)if (input.isKeyReleased('Space')) { releaseCharge();}Key Codes
Use standard DOM key codes:
// Letters'KeyA', 'KeyB', ... 'KeyZ'
// Numbers'Digit0', 'Digit1', ... 'Digit9'
// Special keys'Space', 'Enter', 'Escape', 'Tab''ShiftLeft', 'ShiftRight', 'ControlLeft', 'ControlRight'
// Arrow keys'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'
// Function keys'F1', 'F2', ... 'F12'Mouse Input
const mousePos = input.getMousePosition();console.log(`Mouse at: ${mousePos.x}, ${mousePos.y}`);
if (input.isMouseButtonDown(0)) { // Left button // handle click}if (input.isMouseButtonDown(2)) { // Right button // handle right click}
// Just pressed / released this frameif (input.isMouseButtonPressed(0)) { onClickStart();}if (input.isMouseButtonReleased(0)) { onClickEnd();}Scroll Input
const scroll = input.getScrollDelta();if (scroll.y !== 0) { zoomCamera(scroll.y);}Touch Input
Touch input is unified with mouse input for cross-platform support:
if (input.isMouseButtonDown(0)) { const pos = input.getMousePosition(); handleTap(pos.x, pos.y);}Example: Player Movement
Define Player and MoveSpeed components, attach them to an entity in the scene editor, then write a movement system:
import { defineSystem, defineComponent, defineTag, addSystem, Res, Input, Time, Query, Mut, Transform} from 'esengine';
const Player = defineTag('Player');const MoveSpeed = defineComponent('MoveSpeed', { value: 200 });
addSystem(defineSystem( [Res(Input), Res(Time), Query(Mut(Transform), MoveSpeed, Player)], (input, time, query) => { for (const [entity, transform, speed] of query) { const velocity = { x: 0, y: 0 };
if (input.isKeyDown('KeyW') || input.isKeyDown('ArrowUp')) { velocity.y = -1; } if (input.isKeyDown('KeyS') || input.isKeyDown('ArrowDown')) { velocity.y = 1; } if (input.isKeyDown('KeyA') || input.isKeyDown('ArrowLeft')) { velocity.x = -1; } if (input.isKeyDown('KeyD') || input.isKeyDown('ArrowRight')) { velocity.x = 1; }
const len = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y); if (len > 0) { velocity.x /= len; velocity.y /= len; }
transform.position.x += velocity.x * speed.value * time.delta; transform.position.y += velocity.y * speed.value * time.delta; } }));Next Steps
- UI Interaction — UI interaction events (click, hover, press)
- Physics — physics-driven movement and collision
- Systems — defining and scheduling systems