BemÀstra GamePad API för smidig integration av spelkontroller över olika plattformar. LÀr dig om knappmappning, axelhantering, webblÀsarkompatibilitet och avancerade tekniker.
GamePad API: En omfattande guide till hantering av indata frÄn spelkontroller
GamePad API erbjuder ett standardiserat sÀtt att komma Ät spelkontroller direkt frÄn webblÀsare. Detta öppnar upp spÀnnande möjligheter för att skapa uppslukande och interaktiva webbaserade spel och applikationer. Denna omfattande guide kommer att gÄ igenom allt du behöver veta för att utnyttja GamePad API effektivt, frÄn grundlÀggande installation till avancerade tekniker.
Vad Àr GamePad API?
GamePad API Àr ett JavaScript-API som lÄter webbapplikationer upptÀcka och svara pÄ indata frÄn spelkontroller (gamepads, joysticks, etc.). Det gör det möjligt för utvecklare att bygga spel och interaktiva upplevelser som kan styras med vanliga spelkontrollsinmatningar, sÄsom knappar, axlar (analoga spakar) och avtryckare.
Innan GamePad API var hanteringen av indata frÄn spelkontroller i webblÀsare en fragmenterad och opÄlitlig upplevelse, som ofta krÀvde webblÀsarspecifika insticksprogram eller komplexa lösningar. GamePad API erbjuder en konsekvent och webblÀsaröverskridande lösning, vilket förenklar processen att integrera stöd för spelkontroller i webbapplikationer.
WebblÀsarkompatibilitet
GamePad API stöds brett i moderna webblÀsare, inklusive:
- Chrome (dator och mobil)
- Firefox (dator och mobil)
- Safari (dator och mobil, med vissa begrÀnsningar)
- Edge
- Opera
Ăven om stödet i webblĂ€sare generellt Ă€r bra kan det finnas subtila skillnader i implementation och funktionstillgĂ€nglighet mellan olika webblĂ€sare. Det Ă€r alltid en god praxis att testa din applikation i flera webblĂ€sare för att sĂ€kerstĂ€lla ett konsekvent beteende.
Komma igÄng med GamePad API
HÀr Àr en steg-för-steg-guide för att komma igÄng med GamePad API:
1. UpptÀcka anslutning av spelkontroll
Metoden navigator.getGamepads()
returnerar en array av Gamepad
-objekt, som representerar de för nÀrvarande anslutna spelkontrollerna. WebblÀsaren kommer att avfyra gamepadconnected
- och gamepaddisconnected
-hÀndelser nÀr spelkontroller ansluts eller kopplas frÄn. Du kan lyssna efter dessa hÀndelser för att uppdatera din applikations tillstÄnd.
window.addEventListener("gamepadconnected", function(e) {
console.log("Spelkontroll ansluten vid index %d: %s. %d knappar, %d axlar.",
e.gamepad.index, e.gamepad.id, e.gamepad.buttons.length, e.gamepad.axes.length);
gamepadHandler(e, true);
});
window.addEventListener("gamepaddisconnected", function(e) {
console.log("Spelkontroll frÄnkopplad frÄn index %d: %s",
e.gamepad.index, e.gamepad.id);
gamepadHandler(e, false);
});
function gamepadHandler(event, connecting) {
var gamepad = event.gamepad;
if (connecting) {
gamepads[gamepad.index] = gamepad;
} else {
delete gamepads[gamepad.index];
}
}
var gamepads = {};
Detta kodstycke sÀtter upp hÀndelselyssnare för gamepadconnected
- och gamepaddisconnected
-hÀndelser. Funktionen gamepadHandler
uppdaterar ett gamepads
-objekt för att hÄlla reda pÄ anslutna spelkontroller.
2. AvfrÄgning av spelkontrollens status
GamePad API Àr primÀrt hÀndelsestyrt, men för kontinuerlig inmatning (som rörelse med analog spak) mÄste du avfrÄga spelkontrollens status i en requestAnimationFrame-loop. Detta innebÀr att anropa navigator.getGamepads()
upprepade gÄnger och undersöka egenskaperna buttons
och axes
hos Gamepad
-objekten.
function update() {
var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
for (var i = 0; i < gamepads.length; i++) {
var gp = gamepads[i];
if (gp) {
// Bearbeta spelkontrollens indata hÀr
for (var j = 0; j < gp.buttons.length; j++) {
if (gp.buttons[j].pressed) {
console.log("Knapp " + j + " nedtryckt");
}
}
for (var j = 0; j < gp.axes.length; j++) {
console.log("Axel " + j + ": " + gp.axes[j]);
}
}
}
requestAnimationFrame(update);
}
requestAnimationFrame(update);
Detta kodstycke uppdaterar kontinuerligt spelkontrollens status med hjÀlp av requestAnimationFrame
. Det itererar genom de anslutna spelkontrollerna och kontrollerar statusen pÄ deras knappar och axlar.
3. FörstÄ spelkontrollens egenskaper
Varje Gamepad
-objekt har följande nyckelegenskaper:
id
: En strÀng som identifierar spelkontrollen (t.ex. "Xbox Controller (XInput STANDARD GAMEPAD)").index
: Indexet för spelkontrollen inavigator.getGamepads()
-arrayen.connected
: Ett booleskt vÀrde som anger om spelkontrollen Àr ansluten.buttons
: En array avGamepadButton
-objekt, som representerar spelkontrollens knappar.axes
: En array av tal, som representerar spelkontrollens axlar (analoga spakar och avtryckare).mapping
: En strÀng som anger spelkontrollens knappmappning (antingen "standard" eller "").
4. Arbeta med spelkontrollens knappar
Varje GamepadButton
-objekt har följande egenskaper:
pressed
: Ett booleskt vÀrde som anger om knappen Àr nedtryckt.value
: Ett tal mellan 0 och 1 som representerar trycket som appliceras pÄ knappen (för tryckkÀnsliga knappar som avtryckare).
Du kan komma Ät en knapps status med hjÀlp av dess index i buttons
-arrayen. Till exempel skulle gamepad.buttons[0].pressed
returnera true
om den första knappen Àr nedtryckt.
5. Arbeta med spelkontrollens axlar
axes
-arrayen innehÄller tal som representerar vÀrdena frÄn spelkontrollens analoga spakar och avtryckare. VÀrdena varierar vanligtvis frÄn -1 till 1, dÀr -1 representerar den vÀnstra/översta positionen och 1 representerar den högra/nedersta positionen.
Du kan komma Ät en axels vÀrde med hjÀlp av dess index i axes
-arrayen. Till exempel skulle gamepad.axes[0]
returnera den horisontella positionen för den vÀnstra analoga spaken.
Standardmappning för spelkontroller
GamePad API definierar en "standard"-mappning för spelkontroller som erbjuder ett konsekvent sÀtt att komma Ät vanliga knappar och axlar, oavsett specifik spelkontrollsmodell. Denna mappning identifieras genom att egenskapen mapping
Ă€r satt till "standard".
Standardmappningen för spelkontroller inkluderar följande knappar:
- Knapp 0: A (vanligtvis den nedre högra knappen)
- Knapp 1: B (vanligtvis den högra knappen)
- Knapp 2: X (vanligtvis den vÀnstra knappen)
- Knapp 3: Y (vanligtvis den övre knappen)
- Knapp 4: VĂ€nster bumper (LB)
- Knapp 5: Höger bumper (RB)
- Knapp 6: VĂ€nster avtryckare (LT)
- Knapp 7: Höger avtryckare (RT)
- Knapp 8: Select (eller Back)
- Knapp 9: Start
- Knapp 10: VĂ€nster spak-knapp (LS)
- Knapp 11: Höger spak-knapp (RS)
- Knapp 12: Styrkors Upp
- Knapp 13: Styrkors Ner
- Knapp 14: Styrkors VĂ€nster
- Knapp 15: Styrkors Höger
- Knapp 16: Guide (eller Home)
Standardmappningen för spelkontroller inkluderar följande axlar:
- Axel 0: VÀnster spak, horisontell axel (-1 = vÀnster, 1 = höger)
- Axel 1: VĂ€nster spak, vertikal axel (-1 = upp, 1 = ner)
- Axel 2: Höger spak, horisontell axel (-1 = vÀnster, 1 = höger)
- Axel 3: Höger spak, vertikal axel (-1 = upp, 1 = ner)
Det Àr viktigt att notera att inte alla spelkontroller stöder standardmappningen. Spelkontroller som inte stöder standardmappningen kommer att ha en tom strÀng för egenskapen mapping
, och du mÄste anvÀnda egenskapen id
för att identifiera spelkontrollen och mappa dess knappar och axlar dÀrefter.
Hantering av icke-standardiserade spelkontroller
NÀr du hanterar icke-standardiserade spelkontroller mÄste du identifiera spelkontrollen baserat pÄ dess id
-egenskap och skapa en anpassad mappning för dess knappar och axlar. Detta kan vara en utmanande uppgift, eftersom det finns mÄnga olika modeller av spelkontroller tillgÀngliga, var och en med sin egen unika layout för knappar och axlar.
HÀr Àr nÄgra strategier för att hantera icke-standardiserade spelkontroller:
- Spelkontrollsdatabas: Skapa en databas med
id
-strÀngar för spelkontroller och deras motsvarande knapp- och axelmappningar. Detta gör att du automatiskt kan mappa knappar och axlar för kÀnda spelkontroller. - AnvÀndarkonfiguration: LÄt anvÀndare konfigurera knapp- och axelmappningarna för sina spelkontroller. Detta ger flexibilitet för anvÀndare med ovanliga spelkontroller.
- Heuristisk mappning: AnvÀnd heuristik för att gissa knapp- och axelmappningar baserat pÄ antalet knappar och axlar och deras typiska anvÀndningsmönster.
Att implementera stöd för ett brett utbud av spelkontroller kan vara ett betydande Ă„tagande. ĂvervĂ€g att först fokusera pĂ„ att stödja de mest populĂ€ra spelkontrollsmodellerna och gradvis lĂ€gga till stöd för fler spelkontroller vid behov.
Avancerade tekniker
1. Dödzoner
Analoga spakar har ofta en "dödzon" runt mittpositionen dÀr det rapporterade vÀrdet inte Àr noll Àven nÀr spaken inte rörs. Detta kan orsaka oönskad rörelse eller darrningar i ditt spel. För att ÄtgÀrda detta kan du implementera en dödzon genom att sÀtta axelvÀrdet till noll om det faller inom ett visst intervall runt noll.
function applyDeadZone(value, threshold) {
var percentage = (Math.abs(value) - threshold) / (1 - threshold);
if (percentage < 0) {
percentage = 0;
}
return percentage * (value > 0 ? 1 : -1);
}
var axisValue = gamepad.axes[0];
var deadZoneThreshold = 0.1;
var adjustedAxisValue = applyDeadZone(axisValue, deadZoneThreshold);
Detta kodstycke tillÀmpar en dödzon pÄ axelvÀrdet. Om det absoluta vÀrdet av axeln Àr mindre Àn deadZoneThreshold
, kommer det justerade vÀrdet att vara noll. Annars kommer det justerade vÀrdet att skalas till intervallet 0-1, med bibehÄllet tecken frÄn det ursprungliga vÀrdet.
2. Exponentiell utjÀmning
Indata frÄn analoga spakar kan ibland vara brusig, vilket orsakar ryckiga eller oförutsÀgbara rörelser. För att jÀmna ut indatan kan du tillÀmpa exponentiell utjÀmning. Detta innebÀr att man berÀknar ett medelvÀrde av det aktuella inmatningsvÀrdet och det föregÄende utjÀmnade vÀrdet, med mer vikt pÄ det föregÄende vÀrdet.
var smoothedAxisValue = 0;
var smoothingFactor = 0.1;
function smoothAxisValue(axisValue) {
smoothedAxisValue = smoothingFactor * axisValue + (1 - smoothingFactor) * smoothedAxisValue;
return smoothedAxisValue;
}
var axisValue = gamepad.axes[0];
var smoothedValue = smoothAxisValue(axisValue);
Detta kodstycke tillÀmpar exponentiell utjÀmning pÄ axelvÀrdet. smoothingFactor
bestÀmmer vikten som ges till det aktuella vÀrdet. En mindre utjÀmningsfaktor resulterar i en jÀmnare men mer fördröjd inmatning.
3. Knapp-avstudsning (Debouncing)
Knappar kan ibland utlösa flera hÀndelser nÀr de trycks ner eller slÀpps pÄ grund av mekanisk studs. Detta kan orsaka oavsiktligt beteende i ditt spel. För att ÄtgÀrda detta kan du implementera knapp-avstudsning. Detta innebÀr att man ignorerar knapphÀndelser som intrÀffar inom en kort tidsperiod efter en föregÄende hÀndelse.
var buttonStates = {};
var debounceDelay = 100; // millisekunder
function handleButtonPress(buttonIndex) {
if (!buttonStates[buttonIndex] || Date.now() - buttonStates[buttonIndex].lastPress > debounceDelay) {
console.log("Knapp " + buttonIndex + " nedtryckt (avstudsad)");
buttonStates[buttonIndex] = { lastPress: Date.now() };
// Utför ÄtgÀrd hÀr
}
}
for (var j = 0; j < gp.buttons.length; j++) {
if (gp.buttons[j].pressed) {
handleButtonPress(j);
}
}
Detta kodstycke implementerar knapp-avstudsning. Det hÄller reda pÄ nÀr varje knapp senast trycktes ner. Om en knapp trycks ner igen inom debounceDelay
, ignoreras hÀndelsen.
TillgÀnglighetsaspekter
NÀr man utvecklar spel med stöd för spelkontroller Àr det viktigt att ta hÀnsyn till tillgÀnglighet för spelare med funktionsnedsÀttningar. HÀr Àr nÄgra tips för att göra ditt spel mer tillgÀngligt:
- Konfigurerbara kontroller: LÄt spelare anpassa knapp- och axelmappningarna för att passa deras individuella behov.
- Alternativa inmatningsmetoder: TillhandahÄll alternativa inmatningsmetoder, sÄsom tangentbord och mus, för spelare som inte kan anvÀnda en spelkontroll.
- Tydlig visuell Äterkoppling: Ge tydlig visuell Äterkoppling för alla ÄtgÀrder, sÄ att spelare enkelt kan förstÄ vad som hÀnder i spelet.
- Justerbar svÄrighetsgrad: Erbjud justerbara svÄrighetsgrader för att tillgodose spelare med olika fÀrdighetsnivÄer.
Genom att följa dessa riktlinjer kan du skapa spel som Àr roliga och tillgÀngliga för ett bredare spektrum av spelare.
GamePad API och virtuell verklighet (VR)
GamePad API Àr ocksÄ relevant i samband med WebVR (Virtual Reality pÄ webben). VR-kontroller, som ofta anvÀnds tillsammans med VR-headset, exponeras ofta via GamePad API. Detta gör det möjligt för utvecklare att bygga VR-upplevelser som anvÀnder dessa kontroller för interaktion.
NĂ€r man utvecklar VR-applikationer kan Gamepad
-objektet ha ytterligare egenskaper relaterade till dess pose (position och orientering) i 3D-rymden. Dessa egenskaper nÄs med hjÀlp av egenskapen pose
, som returnerar ett GamePadPose
-objekt. GamePadPose
-objektet ger information om kontrollens position, orientering (som en kvaternion), linjÀr hastighet och vinkelhastighet.
Att anvÀnda GamePad API med WebVR gör det möjligt för utvecklare att skapa uppslukande och interaktiva VR-upplevelser som svarar pÄ anvÀndarens rörelser och interaktioner med VR-kontrollerna.
Exempel: Enkel testare för spelkontroller
HÀr Àr ett enkelt exempel pÄ en testare för spelkontroller som visar statusen för anslutna spelkontroller:
<!DOCTYPE html>
<html>
<head>
<title>Spelkontrollstestare</title>
<style>
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<h1>Spelkontrollstestare</h1>
<div id="gamepads"></div>
<script>
var gamepadsDiv = document.getElementById("gamepads");
var gamepads = {};
function updateGamepads() {
var gamepadList = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
gamepadsDiv.innerHTML = "";
for (var i = 0; i < gamepadList.length; i++) {
var gamepad = gamepadList[i];
if (gamepad) {
var gamepadDiv = document.createElement("div");
gamepadDiv.innerHTML = "<h2>Spelkontroll " + i + ": " + gamepad.id + "</h2>";
var buttonsDiv = document.createElement("div");
buttonsDiv.innerHTML = "<h3>Knappar</h3>";
for (var j = 0; j < gamepad.buttons.length; j++) {
var button = gamepad.buttons[j];
var buttonDiv = document.createElement("div");
buttonDiv.innerHTML = "Knapp " + j + ": Nedtryckt = " + button.pressed + ", VĂ€rde = " + button.value;
buttonsDiv.appendChild(buttonDiv);
}
gamepadDiv.appendChild(buttonsDiv);
var axesDiv = document.createElement("div");
axesDiv.innerHTML = "<h3>Axlar</h3>";
for (var j = 0; j < gamepad.axes.length; j++) {
var axisValue = gamepad.axes[j];
var axisDiv = document.createElement("div");
axisDiv.innerHTML = "Axel " + j + ": " + axisValue;
axesDiv.appendChild(axisDiv);
}
gamepadDiv.appendChild(axesDiv);
gamepadsDiv.appendChild(gamepadDiv);
}
}
}
function update() {
updateGamepads();
requestAnimationFrame(update);
}
window.addEventListener("gamepadconnected", function(e) {
console.log("Spelkontroll ansluten vid index %d: %s. %d knappar, %d axlar.",
e.gamepad.index, e.gamepad.id, e.gamepad.buttons.length, e.gamepad.axes.length);
gamepads[e.gamepad.index] = e.gamepad;
});
window.addEventListener("gamepaddisconnected", function(e) {
console.log("Spelkontroll frÄnkopplad frÄn index %d: %s",
e.gamepad.index, e.gamepad.id);
delete gamepads[e.gamepad.index];
});
requestAnimationFrame(update);
</script>
</body>
</html>
Detta exempel skapar en enkel webbsida som visar information om anslutna spelkontroller, inklusive deras ID, knappstatus och axelvÀrden. Du kan anvÀnda detta exempel som en utgÄngspunkt för att testa och felsöka dina egna GamePad API-applikationer.
BĂ€sta praxis
- AvfrÄga spelkontrollens status: AnvÀnd
requestAnimationFrame
för att regelbundet avfrÄga spelkontrollens status för att sÀkerstÀlla smidig och responsiv inmatning. - Hantera frÄnkopplingar: Lyssna efter
gamepaddisconnected
-hÀndelsen och hantera frÄnkopplingar av spelkontroller pÄ ett elegant sÀtt för att undvika fel. - AnvÀnd standardmappning: AnvÀnd standardmappningen för spelkontroller nÀr det Àr möjligt för att ge en konsekvent upplevelse över olika spelkontroller.
- Erbjud konfigurationsalternativ: LÄt anvÀndare konfigurera knapp- och axelmappningar för att passa deras individuella behov.
- Testa i flera webblÀsare: Testa din applikation i flera webblÀsare för att sÀkerstÀlla ett konsekvent beteende.
- TÀnk pÄ tillgÀnglighet: Utforma ditt spel med tillgÀnglighet i Ätanke för att tillgodose spelare med funktionsnedsÀttningar.
Slutsats
GamePad API erbjuder ett kraftfullt och standardiserat sÀtt att komma Ät spelkontroller frÄn webblÀsare. Genom att bemÀstra GamePad API kan du skapa uppslukande och interaktiva webbaserade spel och applikationer som svarar pÄ anvÀndarens indata frÄn en mÀngd olika spelkontroller.
Denna guide har gett en omfattande översikt över GamePad API, och tÀcker allt frÄn grundlÀggande installation till avancerade tekniker. Genom att följa tipsen och bÀsta praxis som beskrivs i denna guide kan du effektivt integrera stöd för spelkontroller i dina webbapplikationer och skapa engagerande upplevelser för dina anvÀndare.
Kom ihÄg att testa din applikation noggrant i olika webblÀsare och med olika spelkontroller för att sÀkerstÀlla ett konsekvent beteende. TÀnk pÄ tillgÀnglighet för spelare med funktionsnedsÀttningar, och erbjud konfigurationsalternativ för att lÄta anvÀndare anpassa kontrollerna efter eget tycke. Med lite anstrÀngning kan du skapa spel som Àr roliga och tillgÀngliga för ett brett spektrum av spelare.