Hier erfährst du, wie du mit der Gamepad API deine Webspiele auf Erfolgskurs bringst.
Das Easter Egg auf der Offlineseite von Chrome ist eines der am schlechtesten gehüteten Geheimnisse der Geschichte ([citation needed]
,
aber der dramatische Effekt ist die Behauptung. Wenn Sie die Leertaste drücken oder auf einem Mobilgerät
auf den Dinosaurier tippen, wird die Offlineseite zu einem spielbaren Arcade-Spiel. Vielleicht ist Ihnen bewusst, dass
Man muss beim Spielen nicht offline sein: In Chrome navigieren Sie einfach
zu about://dino
oder, für den Geek in dir, zu about://network-error/-106
. Aber wussten Sie,
dass es
Werden jeden Monat 270 Millionen Chrome-Dinospiele gespielt?
![Offlineseite von Chrome mit dem Chrome-Dino-Spiel.](https://web.dev/static/articles/gamepad/image/chromes-offline-page-th-3d966d4a2f411.png?authuser=2&hl=de)
Außerdem ist es sicherlich nützlicher zu wissen, dass man sich im Arcade-Modus, können Sie das Spiel mit einem Gamepad spielen. Die Gamepad-Unterstützung wurde vor etwa einem Jahr als dieses Schreibens in einer commit durch Reilly Grant: Wie ihr seht, ist das Spiel genau wie der Rest wurde vollständig Open Source. In zeige ich Ihnen, wie Sie die Gamepad API verwenden können.
Gamepad API verwenden
Funktionserkennung und Browserunterstützung
Die Gamepad API bietet eine allgemeine Browserunterstützung auf und Mobilgeräte. Anhand des folgenden Snippets können Sie feststellen, ob die Gamepad API unterstützt wird:
if ('getGamepads' in navigator) {
// The API is supported!
}
Darstellung eines Gamepads im Browser
Der Browser stellt Gamepads als Gamepad
dar.
Objekte. Ein Gamepad
hat die folgenden Attribute:
id
: Ein Identifizierungsstring für das Gamepad. Diese Zeichenfolge identifiziert die Marke oder den Stil von verbundenem Gamepad-Gerät.displayId
: DieVRDisplay.displayId
von verknüpfteVRDisplay
(falls relevant).index
: Index des Gamepads im Navigator.connected
: Gibt an, ob das Gamepad noch mit dem System verbunden ist.hand
: Eine Aufzählung, in der definiert wird, in welcher Hand der Controller gehalten wird oder in welcher wahrscheinlich er gehalten wird .timestamp
: Der Zeitpunkt, zu dem die Daten für dieses Gamepad zuletzt aktualisiert wurden.mapping
: Die für dieses Gerät verwendete Zuordnung von Schaltflächen und Achsen, entweder"standard"
oder"xr-standard"
pose
: EinGamepadPose
-Objekt. Sie stellen die Positionsinformationen dar, die mit einem WebVR-Controller verknüpft sind.axes
: ein Array von Werten für alle Achsen des Gamepads, linear auf den Bereich von-1.0
–1.0
.buttons
: Eine Reihe von Schaltflächenstatus für alle Tasten des Gamepads.
Hinweis: Tasten können digital (gedrückt oder nicht gedrückt) oder analog (z. B. zu 78% gedrückt) sein. Dieses
werden Schaltflächen als GamepadButton
-Objekte mit den folgenden Attributen gemeldet:
pressed
: Der gedrückte Zustand der Schaltfläche (true
, wenn die Taste gedrückt wird, undfalse
wenn sie nicht gedrückt wird.touched
: Der berührte Status der Schaltfläche. Wenn die Taste Berührungen erkennen kann, isttrue
, wenn die Schaltfläche berührt wird, andernfallsfalse
.value
: Bei Schaltflächen mit analogem Sensor gibt diese Eigenschaft den Wert an, um den gedrückt, linear auf den Bereich von0.0
–1.0
normalisiert.hapticActuators
: ein Array mitGamepadHapticActuator
-Objekte, die jeweils Hardware für haptisches Feedback darstellen, die auf dem Controller verfügbar ist.
Je nach Browser und Gamepad können Sie auch auf Folgendes stoßen:
ist eine vibrationActuator
-Property. Es gibt zwei Arten von Rumble-Effekten:
- Dual-Rumble: Der haptische Feedback-Effekt, der von zwei exzentrischen rotierenden Masseantrieben erzeugt wird, einer in jedem Griff des Gamepads.
- Trigger-Rumble: Der haptische Feedback-Effekt, der von zwei unabhängigen Motoren erzeugt wird, wobei sich je ein Motor in jedem Trigger des Gamepads befindet.
Die folgende schematische Übersicht direkt aus den Spezifikationen, zeigt die Kartenzuordnung und die Anordnung der Tasten und Achsen auf einem generischen Gamepad.
<ph type="x-smartling-placeholder">Benachrichtigung, wenn ein Gamepad verbunden wird
Wenn Sie wissen möchten, wann ein Gamepad verbunden ist, warten Sie auf das gamepadconnected
-Ereignis, das beim
window
-Objekt. Wenn der Nutzer ein Gamepad anschließt, was entweder über USB oder Bluetooth passiert,
wird ein GamepadEvent
ausgelöst, das die Details des Gamepads in einem passenden gamepad
-Attribut enthält.
Nachfolgend sehen Sie ein Beispiel eines Xbox 360-Controllers, den ich herumgespielt habe.
Retro-Gaming).
window.addEventListener('gamepadconnected', (event) => {
console.log('✅ 🎮 A gamepad was connected:', event.gamepad);
/*
gamepad: Gamepad
axes: (4) [0, 0, 0, 0]
buttons: (17) [GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton]
connected: true
id: "Xbox 360 Controller (STANDARD GAMEPAD Vendor: 045e Product: 028e)"
index: 0
mapping: "standard"
timestamp: 6563054.284999998
vibrationActuator: GamepadHapticActuator {type: "dual-rumble"}
*/
});
Benachrichtigung, wenn die Verbindung zu einem Gamepad getrennt wird
Die Benachrichtigung über Unterbrechungen des Gamepads erfolgt analog zur Erkennung von Verbindungen.
Dieses Mal wartet die App auf das Ereignis gamepaddisconnected
. Beachten Sie, wie im folgenden Beispiel
connected
ist jetzt false
, wenn ich den Xbox 360-Controller trenne.
window.addEventListener('gamepaddisconnected', (event) => {
console.log('❌ 🎮 A gamepad was disconnected:', event.gamepad);
/*
gamepad: Gamepad
axes: (4) [0, 0, 0, 0]
buttons: (17) [GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton]
connected: false
id: "Xbox 360 Controller (STANDARD GAMEPAD Vendor: 045e Product: 028e)"
index: 0
mapping: "standard"
timestamp: 6563054.284999998
vibrationActuator: null
*/
});
Das Gamepad in deiner Spielschleife
Das Abrufen eines Gamepads beginnt mit einem Aufruf von navigator.getGamepads()
, der ein Array zurückgibt
mit Gamepad
Elementen. Das Array in Chrome hat immer eine feste Länge von vier Elementen. Wenn null oder kleiner ist
als vier Gamepads verbunden sind, kann ein Artikel nur „null
“ sein. Achten Sie immer darauf, alle Punkte der
dass sich Gamepads daran erinnern, und sind möglicherweise nicht immer
ersten verfügbaren Slot.
// When no gamepads are connected:
navigator.getGamepads();
// (4) [null, null, null, null]
Wenn ein oder mehrere Gamepads verbunden sind, navigator.getGamepads()
aber immer noch null
Elemente meldet,
musst du eventuell „aufwecken“ indem Sie eine beliebige Taste drücken. Anschließend können Sie das Gamepad abfragen
wie im folgenden Code dargestellt:
const pollGamepads = () => {
// Always call `navigator.getGamepads()` inside of
// the game loop, not outside.
const gamepads = navigator.getGamepads();
for (const gamepad of gamepads) {
// Disregard empty slots.
if (!gamepad) {
continue;
}
// Process the gamepad state.
console.log(gamepad);
}
// Call yourself upon the next animation frame.
// (Typically this happens every 60 times per second.)
window.requestAnimationFrame(pollGamepads);
};
// Kick off the initial game loop iteration.
pollGamepads();
Vibrationsbetätiger
Das Attribut vibrationActuator
gibt ein GamepadHapticActuator
-Objekt zurück, das einem
Konfiguration von Motoren oder anderen Bedienelementen, die eine Kraft zum Zweck der Haptik anwenden können
Feedback geben. Haptische Effekte können durch Aufrufen von Gamepad.vibrationActuator.playEffect()
abgespielt werden. Die einzige
Gültige Effekttypen sind 'dual-rumble'
und 'trigger-rumble'
.
Unterstützte Rumble-Effekte
if (gamepad.vibrationActuator.effects.includes('trigger-rumble')) {
// Trigger rumble supported.
} else if (gamepad.vibrationActuator.effects.includes('dual-rumble')) {
// Dual rumble supported.
} else {
// Rumble effects aren't supported.
}
Doppeltes Ruckeln
„Dual-rumble“ beschreibt eine haptische Konfiguration mit einem Exzentrische rotierende Massenvibration an jedem Griff eines Standard-Gamepads Bei dieser Konfiguration können beide Motoren das gesamte Gamepad vibrieren. Die beiden Massen sind ungleich, können miteinander kombiniert werden, um komplexere haptische Effekte zu erzeugen. Dual-Rumble-Effekte durch vier Parameter definiert:
duration
: legt die Dauer des Vibrationseffekts in Millisekunden fest.startDelay
: Legt die Dauer der Verzögerung bis zum Einsetzen der Vibration fest.strongMagnitude
undweakMagnitude
: Stellen Sie die Vibrationsintensität auf das leichtere exzentrische rotierende Massenmotoren, normalisiert auf den Bereich von0.0
–1.0
.
// This assumes a `Gamepad` as the value of the `gamepad` variable.
const dualRumble = (gamepad, delay = 0, duration = 100, weak = 1.0, strong = 1.0) => {
if (!('vibrationActuator' in gamepad)) {
return;
}
gamepad.vibrationActuator.playEffect('dual-rumble', {
// Start delay in ms.
startDelay: delay,
// Duration in ms.
duration: duration,
// The magnitude of the weak actuator (between 0 and 1).
weakMagnitude: weak,
// The magnitude of the strong actuator (between 0 and 1).
strongMagnitude: strong,
});
};
Trigger-Rumble
Das Trigger-Rumble ist der haptische Feedback-Effekt, der von zwei unabhängigen Motoren erzeugt wird, wobei sich je ein Motor in jedem Trigger des Gamepads befindet.
// This assumes a `Gamepad` as the value of the `gamepad` variable.
const triggerRumble = (gamepad, delay = 0, duration = 100, weak = 1.0, strong = 1.0) => {
if (!('vibrationActuator' in gamepad)) {
return;
}
// Feature detection.
if (!('effects' in gamepad.vibrationActuator) || !gamepad.vibrationActuator.effects.includes('trigger-rumble')) {
return;
}
gamepad.vibrationActuator.playEffect('trigger-rumble', {
// Duration in ms.
duration: duration,
// The left trigger (between 0 and 1).
leftTrigger: leftTrigger,
// The right trigger (between 0 and 1).
rightTrigger: rightTrigger,
});
};
Integration in Berechtigungsrichtlinie
Die Gamepad API-Spezifikation definiert eine
richtliniengesteuerte Funktion des
String "gamepad"
. Der Standardwert für allowlist
ist "self"
. Die Berechtigungsrichtlinie eines Dokuments legt fest,
ob Inhalte in diesem Dokument auf navigator.getGamepads()
zugreifen dürfen. Wenn deaktiviert in
in keinem Dokument verwendet werden darf, darf navigator.getGamepads()
weder verwendet noch
werden die Ereignisse gamepadconnected
und gamepaddisconnected
ausgelöst.
<iframe src="index.html" allow="gamepad"></iframe>
Demo
Im folgenden Beispiel ist eine Gamepad-Tester-Demo eingebettet. Quellcode ist bei Glitch verfügbar. Testen Sie die Demo, indem Sie eine Verbindung zu einem über USB oder Bluetooth und das Drücken einer beliebigen Taste oder das Verschieben einer Achse.
Bonus: Chrome-Dino auf web.dev spielen
Sie können auf diesem Gamepad mit Chrome Dino spielen
auf meiner Website. Der Quellcode ist auf GitHub verfügbar.
Testen Sie die Gamepad-Polling-Implementierung in
trex-runner.js
und achten Sie darauf,
wie Tastendruck emuliert wird.
Damit die Demo des Chrome-Dino-Gamepads funktioniert, habe ich das Chrome-Dino-Spiel aus dem Chromium-Kernprojekt herausrissen (durch Aktualisierung eines früheren Aufwand durch Arnelle Ballane platzierte sie auf einer eigenständigen Website, vorhandene Gamepad-API-Implementierung durch Hinzufügen von Ducking- und Vibrationseffekten, erstellten eine Vollbild- und Mehul Satardekar einen dunklen Modus Implementierung. Viel Spaß beim Spielen!
Nützliche Links
Danksagungen
Dieses Dokument wurde von François Beaufort geprüft und Joe Medley. Die Gamepad API-Spezifikation wird von Steve Agoston James Hollyer und Matt Reynolds Die ehemaligen Spezifikationseditoren Brandon Jones, Scott Graham und Ted Mielczarek Die Spezifikation für Gamepad-Erweiterungen wird bearbeitet von Brandon Jones. Hero-Image von Laura Torrent Puig.