Start · Sprachen · JavaScript · Referenz · Navigator.getGamepads()

Navigator.getGamepads()

Methode

Gibt ein Array mit <code>Gamepad</code>-Objekten (oder <code>null</code>) für alle an das Gerät angeschlossenen Gamepads zurück – als Momentaufnahme ihres aktuellen Zustands.

seit JavaScript Baseline: alle modernen Browser (seit 2017) Kategorie: webapi

Signatur

Navigator.prototype.getGamepads()

Beschreibung

navigator.getGamepads() ist der zentrale Einstiegspunkt der Gamepad API. Die Methode liefert ein Array, dessen Indizes den Gamepad.index-Werten der verbundenen Controller entsprechen. Freie Plätze, etwa nach dem Trennen eines Controllers, enthalten null. Das Array ist also dünn besetzt und kann Lücken haben.

Anders als bei Tastatur- oder Mausereignissen gibt es für Tastendrücke und Stickbewegungen keine Events. Den Zustand liest man stattdessen in einer Schleife ab, meist mit requestAnimationFrame(). Die Events gamepadconnected und gamepaddisconnected melden nur, dass ein Controller angeschlossen oder getrennt wurde.

In Chromium-basierten Browsern sind die zurückgegebenen Gamepad-Objekte Momentaufnahmen. Sie werden nicht automatisch aktualisiert. Deshalb sollte man getGamepads() in jedem Frame neu aufrufen, statt eine alte Referenz aus dem gamepadconnected-Event zu behalten. So verhält sich der Code in allen Browsern gleich.

Jedes Gamepad enthält unter anderem id, index, connected, mapping, timestamp, das Array buttons (Objekte vom Typ GamepadButton mit pressed, touched und value) sowie axes (Zahlen von -1 bis 1).

Rückgabewert

Typ
Array<Gamepad | null>
Beschreibung
Ein Array mit einem Gamepad-Objekt pro angeschlossenem Controller. Leere Plätze sind null. Solange der Nutzer noch keinen Knopf am Controller gedrückt hat, ist das Array leer oder enthält nur null.

Beispiele

Verbundene Gamepads auflisten

// Erst nach einem Tastendruck am Controller sichtbar
window.addEventListener('gamepadconnected', () => {
  const pads = navigator.getGamepads().filter(Boolean);
  for (const pad of pads) {
    console.log(`#${pad.index}: ${pad.id} (${pad.buttons.length} Tasten, ${pad.axes.length} Achsen, Mapping: ${pad.mapping || 'keins'})`);
  }
});
#0: Xbox 360 Controller (XInput STANDARD GAMEPAD) (17 Tasten, 4 Achsen, Mapping: standard)

Spielschleife mit Polling per requestAnimationFrame

const DEADZONE = 0.15;
const player = { x: 0, y: 0 };

const applyDeadzone = (v) => (Math.abs(v) < DEADZONE ? 0 : v);

const loop = () => {
  // In jedem Frame neu abfragen – Objekte sind Momentaufnahmen
  const pad = navigator.getGamepads()[0];
  if (pad) {
    player.x += applyDeadzone(pad.axes[0]) * 5;
    player.y += applyDeadzone(pad.axes[1]) * 5;

    // Taste 0 = A (Xbox) bzw. Kreuz (PlayStation) bei mapping 'standard'
    if (pad.buttons[0].pressed) {
      console.log('Sprung!', player);
    }
  }
  requestAnimationFrame(loop);
};

requestAnimationFrame(loop);
Sprung! { x: 42.5, y: -10 }

Tastendruck-Flanken erkennen (gedrückt statt gehalten)

let previous = [];

const poll = () => {
  const pad = navigator.getGamepads().find((p) => p?.connected);
  if (pad) {
    pad.buttons.forEach((btn, i) => {
      if (btn.pressed && !previous[i]) {
        console.log(`Taste ${i} gedrückt (Wert ${btn.value.toFixed(2)})`);
      }
    });
    previous = pad.buttons.map((b) => b.pressed);
  }
  requestAnimationFrame(poll);
};

window.addEventListener('gamepadconnected', () => requestAnimationFrame(poll), { once: true });
Taste 7 gedrückt (Wert 0.83)

// Wichtig · Fallstricke

  • Datenschutz beim Fingerprinting: Browser zeigen Gamepads erst an, wenn der Nutzer auf der Seite einen Knopf gedrückt oder einen Stick bewegt hat. Vorher liefert getGamepads() nur leere Einträge oder null. Auf diese erste Eingabe sollte man mit gamepadconnected warten.
  • Sicherer Kontext: Die Gamepad API ist nur über HTTPS (oder localhost) verfügbar. In Iframes kann die Permissions-Policy gamepad den Zugriff sperren. Dann wirft der Aufruf einen SecurityError.
  • Einträge mit null: Vor dem Zugriff immer auf null prüfen, z. B. mit ?. oder .filter(Boolean). Außerdem lieferte ältere Chromium-Versionen eine GamepadList statt eines echten Arrays. Wer sicher gehen will, wandelt das Ergebnis mit Array.from() um.
  • Tastenbelegung: Nur bei mapping === 'standard' ist die Reihenfolge der Tasten und Achsen festgelegt. Bei anderen Controllern unterscheidet sich die Belegung je nach Gerät und Browser.
  • Totzone: Analogsticks liefern selbst in Ruhestellung selten exakt 0. Eine Totzone von etwa 0,1–0,2 verhindert, dass die Spielfigur von selbst wandert.
  • Kompatibilität: Wird in allen aktuellen Browsern unterstützt. Das alte navigator.webkitGetGamepads() ist veraltet. Hintergrund-Tabs erhalten oft keine Updates.