Touch controls
Virtual controls render on-screen joysticks and buttons for touch devices. They feed the same InputGamepad fields as physical hardware. Enable them with useVirtualControls from @zylem/game-lib/input, or the higher-level defaultTouchControls helper from @zylem/game-lib/input-ui.
Quick setup with themes
Runnable sample: website/snippets/input/touch-controls.ts.
import { defaultTouchControls } from '@zylem/game-lib/input-ui';
import { mergeInputConfigs, useWASDForAxes } from '@zylem/game-lib/input';
const input = mergeInputConfigs(
useWASDForAxes('p1'),
defaultTouchControls('p1', {
theme: 'lagoon',
joysticks: 'left',
buttons: ['A', 'B'],
}),
);
createGame(player).setInputConfiguration(input).start();
defaultTouchControls builds a VirtualTouchConfig with themed SVG assets, then delegates to useVirtualControls. With enabled: 'auto' (default), the overlay only appears on touch-capable devices—safe to ship on desktop builds.
useVirtualControls (lower level)
useVirtualControls(player, options?) accepts the full VirtualTouchConfig from game config:
joysticks.left/joysticks.right— size, deadzone, axis assignment, custom SVG.buttons.A, … — per-slot layout, labels, andfalseto hide a slot.enabled: true | false | 'auto'— force on for desktop testing.
Joystick configs can set horizontalAxis / verticalAxis to primary or secondary analog fields and optionally emitDirections for digital D-pad output.
Custom art and themes
@zylem/game-lib/input-ui exports:
touchThemes,resolveTouchTheme,resolveButtonAccent- Raw SVG builders:
joystickBaseSvg,joystickThumbSvg,touchButtonSvg
Pass override on defaultTouchControls to merge a raw VirtualTouchConfig when you need pixel-level layout without reimplementing the provider.
Pitfalls
- Touch controls compete for the same axes as keyboard or gamepad; disable desktop keys on mobile-only builds if that causes double movement.
- Trusted SVG strings are injected into the DOM; only use static assets from the library or your own sanitized markup.
- Multiple players need separate
defaultTouchControls('p2', …)entries merged together.