Input · interface

GamepadView

One connected pad, as a consumer holds it.

Explained in Moving things.

interface GamepadView
import type { GamepadView } from '@driftengine/core';

In depth

A view per pad rather than flat accessors on the source, for two reasons: identity belongs to a device and would otherwise be passed alongside every call, and local multiplayer falls out of it instead of needing a second design later.

Properties

NameTypeDescription
indexreadonlynumberThe browser's own slot, so a consumer can keep a player on the pad they picked up.
identityreadonlyGamepadIdentity
mappingreadonly'standard' | 'unknown''standard' when the browser vouches for the layout, 'unknown' when it will not.
More

The named accessors still answer on an unknown pad — they read the standard indices — but they are reading a guess, and this is how a consumer can tell.

canRumblereadonlybooleanWhether this pad has motors this browser can drive.
More

Read it and grey the control out. Most pads on most browsers cannot rumble, and a settings screen offering a slider the player's hardware ignores is worse than one that says so. Re-read it after a poll rather than caching: a pad unplugged and plugged back in is a different device behind the same slot.

Methods

down

down(button: GamepadButton): boolean

Held right now.

ParameterTypeDescription
buttonGamepadButton

pressed

pressed(button: GamepadButton): boolean

Went down since the last poll, readable by anything.

ParameterTypeDescription
buttonGamepadButton
More

Clears at the next poll rather than at the read, so a menu and a heads-up display may both see one press. Use consumePress where acting twice would be a bug.

consumePress

consumePress(button: GamepadButton): boolean

The same edge, claimed — true for exactly one caller, then gone for everybody.

ParameterTypeDescription
buttonGamepadButton
More

The hazard is a slow frame. The fixed-step loop runs more than once, and a pressed that stayed true across both ticks is a double jump from a single press. Anything acting inside simulate claims; anything drawing reads pressed.

axis

axis(axis: GamepadAxis): number

A stick axis with the deadzone applied, in [-1, 1]. Vertical points up at −1.

ParameterTypeDescription
axisGamepadAxis

trigger

trigger(button: 'l2' | 'r2'): number

A lower shoulder's analog travel, in [0, 1]. It is a button and an axis, honestly both.

ParameterTypeDescription
button'l2' | 'r2'

button

button(index: number): boolean

Any button by raw index, for a pad whose layout the browser will not vouch for.

ParameterTypeDescription
indexnumber

rawAxis

rawAxis(index: number): number

Any axis by raw index, untouched by the deadzone.

ParameterTypeDescription
indexnumber

rumble

rumble(durationMs: number, strong: number, weak: number): boolean

Play a rumble for durationMs, at two magnitudes in [0, 1]. Answers whether it was taken.

ParameterTypeDescription
durationMsnumber
strongnumber
weaknumber
More

strong is the low-frequency motor and weak the high-frequency one, which is what a standard pad has two of. Magnitudes are clamped into range and a duration past the platform's ceiling of five seconds is clamped to it; a duration at or below zero is nothing to play and answers false.

false is a real answer and not an error: no actuator, a browser that cannot drive one, or nothing to play. It never throws, and a failure after the fact — the pad unplugged mid-effect — is reported once per pad on the console rather than as an unhandled rejection.

stopRumble

stopRumble(): boolean

Stop whatever is playing. Answers whether the platform took it.