Skip to content

Input Handling

ESEngine provides input handling through the Input resource.

Using Input in Systems

Access input state through the Res(Input) system parameter:

import { defineSystem, Res, Input, Query, LocalTransform } from 'esengine';
defineSystem(
[Res(Input), Query(LocalTransform)],
(input, query) => {
for (const [entity, transform] of query) {
// Move based on input
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

// Check if key is currently held down
if (input.isKeyDown('Space')) {
player.jump();
}
// Check if key was just pressed this frame
if (input.isKeyPressed('Space')) {
player.startJump();
}
// Check if key was just released this frame
if (input.isKeyReleased('Space')) {
player.endJump();
}

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

// Get mouse position
const mousePos = input.getMousePosition();
console.log(`Mouse at: ${mousePos.x}, ${mousePos.y}`);
// Check mouse buttons
if (input.isMouseButtonDown(0)) { // Left button
shoot(mousePos.x, mousePos.y);
}
if (input.isMouseButtonDown(2)) { // Right button
openContextMenu();
}

Touch Input

Touch input is unified with mouse input for cross-platform support:

// Works for both mouse click and touch
if (input.isMouseButtonDown(0)) {
const pos = input.getMousePosition();
handleTap(pos.x, pos.y);
}

Example: Player Movement

import {
defineSystem, defineComponent, Schedule,
Res, Input, Time, Query, LocalTransform
} from 'esengine';
const Player = defineTag('Player');
const MoveSpeed = defineComponent('MoveSpeed', { value: 200 });
// Movement system
app.addSystemToSchedule(Schedule.Update, defineSystem(
[Res(Input), Res(Time), Query(LocalTransform, 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;
}
// Normalize diagonal movement
const len = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
if (len > 0) {
velocity.x /= len;
velocity.y /= len;
}
// Apply movement
transform.position.x += velocity.x * speed.value * time.delta;
transform.position.y += velocity.y * speed.value * time.delta;
}
}
));