Con l'aumentare graduale della popolarità dei giochi HTML, i produttori stanno iniziando a introdurre nuove entusiasmanti API per rendere il gioco un po 'più dolce per noi sviluppatori e per i nostri giocatori finali. Uno di questi è GamepadAPI, che ti permette di collegare il tuo vecchio gamepad per console al tuo computer e usarlo per giochi basati su browser, plug and play style. Tuffiamoci dentro!
In poche parole, l'API Gamepad consente di interagire con il browser utilizzando un controller per console per videogiochi, AKA un gamepad. Questo non richiede un driver o un plugin speciale per funzionare, è semplice come plug and play!
Essendo io stesso un console gamer piuttosto che un giocatore desktop, preferisco di gran lunga interagire con i giochi usando un gamepad, e con l'imminente aumento di giochi basati su HTML e JavaScript, questo diventerà uno strumento davvero utile per rendere i giochi più facilmente accessibili per i tuoi utenti.
L'API Gamepad non è prontamente disponibile per il rilascio pubblico, ma possiamo iniziare a usarla per noi stessi con le versioni di anteprima di Firefox. Quindi, prima di rimanere bloccati, abbiamo bisogno di alcune cose.
Come ho già detto, l'API di Gamepad non è ancora disponibile per la versione pubblica, quindi dovrai prima procurarti una build Nightly di Firefox e assicurarti di avere installato il componente aggiuntivo Firebug (solo a scopo di debug).
Inoltre, non puoi dimenticare un gamepad! Userò un controller per PlayStation 3 per questo tutorial, ma un controller Xbox andrà benissimo.
Una volta installato Nightly e aggiunto Firebug, sei pronto per partire!
(NB: build recenti di Chromium hanno anche il supporto per l'API di Gamepad, ma questo tutorial non è stato testato contro di loro.)
Iniziamo con un file HTML di base (index.html), utilizzando "gamepad.js" (un file JavaScript vuoto).
index.html
Introduzione all'API del gamepad API Gamepad
La connessione di un gamepad viene rilevata con un semplice listener di eventi JavaScript, l'evento attivato viene chiamato "MozGamepadConnected". Quindi la prima cosa che dobbiamo fare è aggiungere un listener di eventi alla finestra per rilevare quell'evento.
Sto anche aggiungendo una funzione di callback che registrerà i dettagli dell'evento nella console di Firebug. Questa è l'informazione che ci interessa di più e che ci permetterà di sapere che abbiamo collegato con successo un gamepad.
function gamepadConnected (evt) console.log (evt); window.addEventListener ('MozGamepadConnected', gamepadConnected);
Esegui index.html in Nightly e apri la console di Firebug, qui potremo vedere la registrazione dell'evento dalla nostra funzione di callback.
Assicurati che il controller sia spento e non connesso in modalità wireless a una console di gioco. Collegalo al computer tramite USB e accendi il controller, guardando il registro degli eventi nella console.
Bene, abbiamo un gamepad che si connette a un browser, non sono richiesti plug-in o driver aggiuntivi!
È altrettanto importante sapere se un gamepad è stato disconnesso, quindi guardiamo l'evento "MozGamepadDisconnected".
Analogamente al primo passaggio, aggiungere un listener di eventi per un evento di disconnessione e una funzione di callback per registrare i dettagli dell'evento.
function gamepadDisconnected (evt) console.log (evt); window.addEventListener ('MozGamepadDisconnected', gamepadDisconnected);
Se il tuo gamepad è ancora connesso, aggiorna la tua pagina (che vedrà la registrazione dell'evento collegato) e poi scollega il gamepad espellendolo dalla porta USB. Dovresti ottenere un registro degli eventi come questo.
Ora sappiamo quando un gamepad è stato connesso e disconnesso, è probabilmente una buona idea registrare lo stato all'interno di una variabile e prepararsi a rilevare gli eventi del pulsante!
var gamepadActive = false; function gamepadConnected (evt) console.log (evt); gamepadActive = true; function gamepadDisconnected (evt) console.log (evt); gamepadActive = false; window.addEventListener ('MozGamepadConnected', gamepadConnected); window.addEventListener ('MozGamepadDisconnected', gamepadDisconnected);
Il pulsante preme, di nuovo, usa un listener di eventi e la funzione di callback con due eventi, "MozGamepadButtonDown" e "MozGamepadButtonUp".
Ti suggerirei di registrare l'intero evento dal pulsante premi te stesso per vedere cosa sta succedendo, ma l'informazione chiave di cui abbiamo bisogno per ottenere da questo evento è evt.button
. Questo è l'identificativo numerico del pulsante che è stato premuto.
La funzione di callback questa volta richiede un secondo parametro, un valore booleano per verificare se il pulsante è stato premuto o rilasciato. Lo impostiamo noi stessi nelle funzioni di callback degli ascoltatori di eventi.
function buttonPressed (evt, pressed) console.log (evt.button, pressed); window.addEventListener ("MozGamepadButtonDown", function (evt) buttonPressed (evt, true);); window.addEventListener ("MozGamepadButtonUp", function (evt) buttonPressed (evt, false););
Ora dovrebbe restituire gli ID dei pulsanti che sono stati premuti e se sono stati premuti o rilasciati (true per i pulsanti in basso, false per i pulsanti in alto).
Quindi creeremo un array con tutti i pulsanti di PlayStation 3. Gli indici dell'array si assoceranno agli ID utilizzati su questo gamepad, con i valori come il nome del pulsante.
var gamepadActive = false, ps3Buttons = new Array (); ps3Buttons [12] = 'triangle', ps3Buttons [15] = 'square', ps3Buttons [14] = 'cross', ps3Buttons [13] = 'circle', ps3Buttons [4] = 'up', ps3Buttons [7] = 'left', ps3Buttons [6] = 'down', ps3Buttons [5] = 'right', ps3Buttons [10] = 'L1', ps3Buttons [8] = 'L2', ps3Buttons [11] = 'R1', ps3Button [9] = 'R2', ps3Buttons [1] = 'L3', ps3Buttons [2] = 'R3', ps3Buttons [16] = 'PS', ps3Buttons [0] = 'seleziona', ps3Buttons [3] = ' inizio';
Se stai utilizzando un controller diverso, prenditi il tempo necessario per capire quale indice va con quale pulsante e memorizza le informazioni in un array simile.
Se ora modifichiamo il buttonPressed ()
funzione mai così poco, possiamo facilmente dire quale pulsante sul controller è stato premuto.
function buttonPressed (evt, pressed) console.log (ps3Buttons [evt.button] + 'è stato premuto');
Provaci! Premendo i pulsanti sul controller dovrebbe ora registrare il nome dei pulsanti da premere. Questo sarà molto più facile da capire di "pulsante 5" (che, nel mio caso, è sul D-pad).
Rilevare gli eventi dell'asse è fondamentalmente tenere traccia di dove sono posizionate le levette analogiche sinistra e destra sul gamepad usando l'evento "MozGamepadAxisMove".
Aggiungi il nuovo gestore di eventi e la funzione di callback.
function moveAnalogSticks (evt) console.log (evt.axis, evt.value); window.addEventListener ("MozGamepadAxisMove", moveAnalogSticks);
Questo è ciò che otteniamo - confuso, giusto?
C'è solo un evento sparato da entrambe le levette analogiche; ogni evento ci dà uno dei quattro possibili assi e un valore compreso tra -1.0 e +1.0. L'asse 0 e 1 appartengono allo stick analogico sinistro e gli assi 2 e 3 appartengono alla destra.
Nel diagramma sopra vedrai gli assi 0 e 2 che corrispondono all'asse x, e 1 e 3 corrispondono all'asse y. Usando entrambi gli assi xey per ogni singolo stick analogico, è possibile capire in che direzione si trova la levetta analogica!
Su diversi gamepad, potresti avere altri assi. Ad esempio, i trigger a spalla su un controller Xbox sono anche analogici.
Questo copre tutti gli eventi che possiamo attualmente prendere da un gamepad, quindi mettiamo in pratica ciò che abbiamo imparato.
Ora, non voglio entrare troppo nel lato dello sviluppo del gioco, poiché ci stiamo concentrando su ciò che usiamo per controllare i giochi stessi. Uno degli aspetti chiave da considerare, tuttavia, è il passaggio a schemi di controllo. Poiché non tutti avranno a disposizione un gamepad, dobbiamo assicurarci di fornire controlli sia per la tastiera che per il gamepad.
Per avviare e avviare una piccola demo, creare a tela
elemento nel tuo file html con un id di "gioco" e imposta la larghezza a 600 e l'altezza a 540. Come forse saprai, l'elemento canvas è comunemente usato per il rendering di giochi HTML su.
Dovrai anche copiare le immagini "ship.png" e "space.jpg" dal download sorgente nella tua cartella di lavoro, poiché queste sono le immagini che verranno renderizzate sulla tela. In alternativa, trova qualche grafica per giocare!
Introduzione all'API del gamepad API Gamepad
Ora che il tela
elemento è nel nostro DOM, vogliamo creare un ciclo di gioco per rendere il nostro gioco.
Sto usando uno shim per "requestAnimationFrame" di Paul Irish che sarà la base del nostro ciclo. Successivamente, otteniamo il contesto 2D del tela
che useremo per disegnare e creare due nuovi oggetti immagine, uno per lo sfondo e uno per la nostra astronave.
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ window.requestAnimFrame = (function () return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (/ * function * / callback, / * DOMElement * / element) window.setTimeout (callback, 1000/60);;) (); var canvas = document.getElementById ('game'), ctx = canvas.getContext ('2d'), ship = new Image (), space = new Image (); space.src = "space.jpg"; ship.src = "ship.png";
Quindi, l'oggetto giocatore. Ha coordinate xey che tengono traccia di dove dovrebbe apparire sulla tela; quattro stati di direzione (su, giù, sinistra e destra) in modo che possiamo sapere da che parte si muove la nave; un render ()
funzione, che prima chiama updatePosition ()
e quindi disegna l'immagine della nave sulla tela in base alle coordinate xey, e infine la updatePosition ()
funzione stessa, che verifica per vedere in che modo la nave è impostata per muoversi e aggiorna la sua posizione di conseguenza.
var player = x: 200, y: 250, su: false, down: false, left: false, right: false, render: function () this.updatePosition (); ctx.drawImage (nave, this.x, this.y); , updatePosition: function () this.up? this.y--: false; questo.down? this.y ++: false; questo.left? this.x--: false; questo bene? this.x ++: false;
Dopo di che abbiamo la nostra funzione "renderGame" che disegna l'immagine di sfondo dello spazio sul tela
in primo luogo, quindi disegna la nostra astronave in cima a quello.
E infine, il nostro ciclo. Questa funzione chiama se stessa ancora e ancora, chiamando ogni volta la nostra funzione "renderGame".
function renderGame () ctx.drawImage (spazio, 0,0); player.render (); ; (funzione animloop () requestAnimFrame (animloop); renderGame ();) ();
La tua tela ora dovrebbe avere uno sfondo piacevole con lo sfondo di un'astronave al centro di esso - non troppo eccitante, lo so. Quindi aggiungiamo alcuni controlli!
Nel nostro codice giocatore abbiamo chiamato i quattro pulsanti con i quali vogliamo controllare la nostra nave. Questi corrispondono ai nomi dei pulsanti all'interno del ps3Buttons []
array. Quindi, tutto ciò che dobbiamo fare è modificare il nostro buttonPressed ()
funziona così leggermente e ci sposteremo.
var player = ... up: false, down: false, left: false, right: false, ...
Ora, quando viene premuto o rilasciato un pulsante gamepad, il suo stato verrà impostato all'interno dell'oggetto giocatore, quindi quando viene premuto il pulsante "su", player.up = vero / falso
sarà impostato.
function buttonPressed (evt, pressed) console.log (evt.button, pressed); player [ps3Buttons [evt.button]] = premuto? vero falso;
Tornate alla vostra demo e dovreste essere in grado di muovere la vostra nave!
Poiché non tutti i tuoi giochi avranno un gamepad, probabilmente vorrai comunque consentire loro di giocare con una tastiera.
Prima creiamo un nuovo tasti []
array e mappare i tasti freccia della tastiera chiave
proprietà ai pulsanti equivalenti sul gamepad. Questo ci permetterà di riutilizzare buttonPressed ()
funzione utilizzata dal gamepad.
var gamepadActive = false, ps3Buttons = new Array (), keys = new Array (); ps3Buttons [12] = 'triangle', ps3Buttons [15] = 'square', ps3Buttons [14] = 'cross', ps3Buttons [13] = 'circle', ps3Buttons [4] = 'up', ps3Buttons [7] = 'left', ps3Buttons [6] = 'down', ps3Buttons [5] = 'right', ps3Buttons [10] = 'L1', ps3Buttons [8] = 'L2', ps3Buttons [11] = 'R1', ps3Button [9] = 'R2', ps3Buttons [1] = 'L3', ps3Buttons [2] = 'R3', ps3Buttons [16] = 'PS', ps3Buttons [0] = 'seleziona', ps3Buttons [3] = ' inizio'; tasti [38] = 4; chiavi [37] = 7; tasti [40] = 6; tasti [39] = 5;
Ora abbiamo bisogno di un listener di eventi "onkeyup" e "onkeydown" per i tasti freccia. Quando un tasto viene premuto o rilasciato, ci assicuriamo che non sia in uso un gamepad. Quindi evitiamo che il tasto freccia esegua il suo solito compito (scorrendo la finestra del browser in alto o in basso in questo caso) e poi chiama lo stesso buttonPressed ()
funzione che chiama il gamepad.
Per fare questo, un oggetto evento falso viene passato con il "keyCode" della chiave mappato su un oggetto nel tasti []
array, che a sua volta passa l'ID del pulsante del gamepad corrispondente.
window.onkeydown = function (evt) if (gamepadActive == false) evt.preventDefault (); buttonPressed (button: keys [evt.keyCode], true); window.onkeyup = function (evt) if (gamepadActive == false) evt.preventDefault (); buttonPressed (pulsante : tasti [evt.keyCode], false);
Ora dovresti usare i tasti freccia per controllare la nave quando un gamepad non è collegato, lasciando comunque che il gamepad prenda il sopravvento quando è presente.
Abbiamo quindi spiegato le basi per collegare un gamepad al tuo computer, imparato come collegare gli eventi attivati dal gamepad e quindi usarli nella pratica. Senza dimenticare, il supporto cruciale per la tastiera!
Una sfida rapida per chi ha un controller diverso da un Dual Shock PS3: regola la mappatura dei pulsanti in base a qualsiasi controller inserito.
Grazie per aver dedicato del tempo per conoscere l'API di Gamepad. Se avete domande, per favore lasciatele nei commenti.