Découvrez comment utiliser l'API Gamepad pour faire passer vos jeux Web au niveau supérieur.
L'easter egg de la page hors connexion de Chrome est l'un des secrets les moins gardés de l'histoire ([citation needed]
,
mais la déclaration faite pour l'effet dramatique). Si vous appuyez sur la touche Espace ou, sur un appareil mobile,
appareils, appuyez sur le dinosaure, la page hors connexion devient un jeu d'arcade jouable. Vous savez peut-être que
Vous n'avez pas besoin de vous déconnecter quand vous voulez jouer. Dans Chrome, il vous suffit de naviguer
à about://dino
ou, si vous êtes un geek, d'accéder à about://network-error/-106
. Mais saviez-vous
qu'il existe
270 millions de jeux de dinosaures sur Chrome joués chaque mois ?
![Page hors connexion de Chrome avec le jeu du dinosaure de Chrome.](https://web.developers.google.cn/static/articles/gamepad/image/chromes-offline-page-th-3d966d4a2f411.png?authuser=0000&hl=fr)
Un autre fait sans doute plus utile à savoir et dont vous n'êtes peut-être pas conscient est que dans mode arcade, vous pouvez jouer avec une manette. La prise en charge des manettes de jeu a été ajoutée il y a environ un an de la rédaction de cet article commit par Reilly Grant. Comme vous pouvez le voir, le jeu, comme le reste Chromium, est entièrement Open Source. Dans ce post, je veux vous montrer comment utiliser l'API Gamepad.
Utiliser l'API Gamepad
Détection de fonctionnalités et compatibilité avec les navigateurs
L'API Gamepad est parfaitement compatible avec les navigateurs, à la fois ordinateurs et mobiles. Vous pouvez vérifier si l'API Gamepad est compatible à l'aide de l'extrait de code suivant:
if ('getGamepads' in navigator) {
// The API is supported!
}
Comment le navigateur représente une manette de jeu
Le navigateur représente les manettes de jeu sous la forme Gamepad
.
d'objets. Un Gamepad
a les propriétés suivantes:
id
: chaîne d'identification de la manette de jeu. Cette chaîne identifie la marque ou le style manette de jeu connectée.displayId
: leVRDisplay.displayId
d'unVRDisplay
associé (le cas échéant).index
: index de la manette de jeu dans le navigateurconnected
: indique si la manette de jeu est toujours connectée au système.hand
: énumération définissant la main dans laquelle la manette est tenue ou qu'elle est le plus susceptible de tenir. po.timestamp
: date de la dernière mise à jour des données de cette manette.mapping
: mappage du bouton et des axes utilisé pour cet appareil ("standard"
ou"xr-standard"
pose
: objetGamepadPose
représentant les informations de pose associées à un contrôleur WebVR.axes
: tableau de valeurs pour tous les axes de la manette de jeu, normalisé linéairement dans la plage des-1.0
–1.0
.buttons
: tableau des états de tous les boutons de la manette de jeu.
Notez que les boutons peuvent être numériques (enfoncé ou non) ou analogiques (par exemple, 78% de la pression). Ce
C'est pourquoi les boutons sont signalés en tant qu'objets GamepadButton
, avec les attributs suivants:
pressed
: état du bouton (true
si l'utilisateur a appuyé dessus etfalse
) si ce n'est pas le cas.touched
: état d'appui sur le bouton. Si le bouton est capable de détecter une pression tactile, esttrue
si un utilisateur appuie sur le bouton, etfalse
dans le cas contraire.value
: pour les boutons équipés d'un capteur analogique, cette propriété représente la quantité de données a appuyé sur le bouton, normalisé de manière linéaire dans la plage comprise entre0.0
et1.0
.hapticActuators
: tableau contenantGamepadHapticActuator
des objets, chacun représentant le matériel de retour haptique disponible sur le contrôleur.
Une autre chose que vous pourriez rencontrer, selon votre navigateur et votre manette de jeu,
est une propriété vibrationActuator
. Il permet deux types d'effets de rumble:
- Dual-Rumble: effet de retour haptique généré par deux actionneurs en masse rotatifs excentriques, un dans chaque prise de la manette de jeu.
- Déclencheur/Rumble: effet de retour haptique généré par deux moteurs indépendants, chacun des déclencheurs de la manette de jeu.
La présentation schématique suivante, prise d'après les spécifications, montre la mise en correspondance et la disposition des boutons et des axes sur une manette de jeu générique.
<ph type="x-smartling-placeholder">Notification lorsqu'une manette de jeu est connectée
Pour savoir quand une manette de jeu est connectée, écoutez l'événement gamepadconnected
qui se déclenche sur la
window
. Lorsque l'utilisateur connecte une manette de jeu, ce qui peut se produire via USB ou Bluetooth,
Déclenchement d'une GamepadEvent
contenant les détails de la manette dans une propriété gamepad
bien nommée.
L'exemple suivant illustre une manette Xbox 360 que je me suis laissée traîner (oui, je suis dans
les jeux rétro).
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"}
*/
});
Notification lorsqu'une manette de jeu est déconnectée
La réception d'une notification en cas de déconnexion de la manette de jeu se fait de la même manière que la détection des connexions.
Cette fois, l'application écoute l'événement gamepaddisconnected
. Notez que dans l'exemple suivant,
connected
est maintenant false
lorsque je débranche la manette Xbox 360.
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
*/
});
La manette de jeu dans votre boucle de jeu
L'obtention d'une manette de jeu commence par un appel à navigator.getGamepads()
, qui renvoie un tableau
avec Gamepad
éléments. Le tableau dans Chrome a toujours une longueur fixe de quatre éléments. Si zéro ou une valeur inférieure
que quatre manettes de jeu sont connectées, un élément peut simplement avoir la valeur null
. Assurez-vous toujours de
vérifier tous les éléments de
le tableau et gardez à l'esprit que les manettes de jeu leur emplacement et ne sont pas toujours présents
le premier emplacement disponible.
// When no gamepads are connected:
navigator.getGamepads();
// (4) [null, null, null, null]
Si une ou plusieurs manettes de jeu sont connectées, mais que navigator.getGamepads()
signale toujours null
éléments,
vous devrez peut-être "réactiver" chaque manette en appuyant
sur l'un de ses boutons. Vous pouvez ensuite interroger la manette
dans votre boucle de jeu, comme illustré dans le code suivant.
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();
L'actionneur des vibrations
La propriété vibrationActuator
renvoie un objet GamepadHapticActuator
, qui correspond à une
configuration de moteurs ou autres actionneurs pouvant appliquer une force pour le retour haptique
commentaires. Vous pouvez exécuter des effets haptiques en appelant Gamepad.vibrationActuator.playEffect()
. La seule
les types d'effets valides sont 'dual-rumble'
et 'trigger-rumble'
.
Effets de rumble compatibles
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.
}
Double rumble
Le double rumble décrit une configuration haptique avec une moteur vibrant à masse rotative excentrique sur chaque poignée d'une manette de jeu standard. Dans cette configuration, l’un ou l’autre des moteurs est capable de faire vibrer l’ensemble de la manette de jeu. Les deux masses sont inégales, les effets de chacun d'eux peuvent être combinés pour créer des effets haptiques plus complexes. Les effets de double vibration sont défini par quatre paramètres:
duration
: définit la durée de l'effet de vibration en millisecondes.startDelay
: définit le délai avant le déclenchement du vibreur.strongMagnitude
etweakMagnitude
: définissez l'intensité des vibrations pour les moteurs à masse rotatif excentriques plus légers, normalisés dans la plage0.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,
});
};
Déclenchement du grondement
Le bruit de fond correspond au retour haptique généré par deux moteurs indépendants, chacun des déclencheurs de la manette de jeu.
// 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,
});
};
Intégration avec les règles d'autorisation
Les spécifications de l'API Gamepad définissent
fonctionnalité contrôlée par des règles identifiée par le
chaîne "gamepad"
. Sa valeur par défaut (allowlist
) est "self"
. La stratégie d'autorisations d'un document détermine
si certains contenus de ce document sont autorisés à accéder à navigator.getGamepads()
. Si désactivé dans
n'importe quel document, aucun contenu ne sera autorisé à utiliser navigator.getGamepads()
, et
les événements gamepadconnected
et gamepaddisconnected
se déclenchent.
<iframe src="index.html" allow="gamepad"></iframe>
Démo
Une démo de testeur de manette de jeu est intégrée dans l'exemple suivant. Le code source est disponible sur Glitch. Essayez la version de démonstration en connectant un manette de jeu via USB ou Bluetooth et en appuyant sur l'un de ses boutons ou en déplaçant n'importe quel axe.
Bonus: Jouez au dinosaure de Chrome sur web.dev
Vous pouvez jouer au dino de Chrome avec votre manette sur ce
sur le site. Le code source est disponible sur GitHub.
Découvrez l'implémentation
de l'interrogation de manette de jeu dans
trex-runner.js
et notez comment il émule les pressions sur les touches.
Pour que la démo de la manette de jeu avec le dinosaure de Chrome fonctionne, a éliminé le jeu du dinosaure de Chrome du projet Chromium principal (mise à jour d'un d'efforts en amont en Arnelle Ballane), l'a placée sur un site autonome, a étendu l'implémentation existante de l'API pour manette de jeu en ajoutant des effets d'atténuation et de vibration, créé un mode plein écran et Mehul Satardekar a contribué au mode sombre la mise en œuvre. Amusez-vous bien !
Liens utiles
Remerciements
Ce document a été révisé par François Beaufort et Joe Medley La spécification de l'API Gamepad est modifiée par Steve Agoston, James Hollyer et Matt Reynolds Les anciens éditeurs de spécifications Brandon Jones, Scott Graham et Ted Mielczarek La spécification des extensions Gamepad est modifiée par Brandon Jones. Image principale par Laura Torrent Puig.