Roll It è un esperimento di Chrome che reinventa un classico gioco da spiaggia utilizzando solo il browser sullo smartphone e sul computer. Il browser sullo smartphone ti consente di mirare e far rotolare la palla con un movimento del polso, mentre il browser sul computer esegue il rendering della grafica in tempo reale della corsia di Roll It con WebGL e Canvas. I due dispositivi comunicano tramite Websockets. Nessuna app. Nessun download. Nessun token. Ti serve solo un browser moderno.
Sotto la direzione di Google Creative Lab, Legwork ha sviluppato l'esperienza utente, le interfacce e l'ambiente di gioco, poi ha collaborato con il partner di sviluppo Mode Set per creare Roll It. Durante la durata del progetto si sono presentate una serie di sfide uniche. Questo articolo illustra alcune delle tecniche che abbiamo utilizzato, i trucchi che abbiamo scoperto e le lezioni che abbiamo imparato durante la realizzazione di Roll It.
Flusso di lavoro 3D
Uno dei problemi iniziali è stato capire il modo migliore per trasferire i modelli 3D dal nostro software a un formato file adatto al web. Dopo aver creato gli asset in Cinema 4D, i modelli sono stati semplificati e convertiti in mesh a basso numero di poligoni. A ogni mesh sono stati assegnati determinati tag di selezione dei poligoni per distinguere le parti dell'oggetto per la colorazione e la texturizzazione. Abbiamo quindi potuto esportare il file come file Collada 1.5 (.dae) e importarlo in Blender, un programma 3D open source, per creare file compatibili con three.js. Dopo aver verificato che i modelli fossero stati importati correttamente, abbiamo esportato il mesh come file JSON e l'illuminazione è stata applicata utilizzando il codice. Ecco un'analisi più dettagliata dei passaggi che abbiamo intrapreso:
Scrittura del codice
Roll è stato sviluppato con librerie open source ed è eseguito in modo nativo nei browser moderni. Con tecnologie come WebGL e WebSocket, il web si sta avvicinando a esperienze multimediali e di gioco con qualità console. La facilità e la comodità con cui gli sviluppatori possono creare queste esperienze hanno fatto passi da gigante con la disponibilità di strumenti più moderni per lo sviluppo HTML.
L'ambiente di sviluppo
La maggior parte del codice originale di Roll It è stata scritta in CoffeeScript, un linguaggio pulito e conciso che viene transcompilato in JavaScript ben formato e sottoposto a lint. CoffeeScript è ideale per lo sviluppo di OOP grazie al suo ottimo modello di ereditarietà e alla gestione più chiara dell'ambito. Il codice CSS è stato scritto con il framework SASS, che offre allo sviluppatore una serie di ottimi strumenti per migliorare e gestire gli stili di un progetto. L'aggiunta di questi sistemi al processo di compilazione richiede un po' di tempo per la configurazione, ma il risultato è sicuramente utile, soprattutto per un progetto più grande come Roll It. Abbiamo configurato un server Ruby on Rails per compilare automaticamente i nostri asset durante lo sviluppo, in modo che tutti questi passaggi di compilazione diventassero trasparenti.
Oltre a creare un ambiente di programmazione semplificato e confortevole, abbiamo ottimizzato manualmente gli asset per ridurre al minimo le richieste e velocizzare il caricamento del sito. Abbiamo sottoposto ogni immagine a un paio di programmi di compressione: ImageOptim e ImageAlpha. Ogni programma ottimizza le immagini a modo suo, rispettivamente senza perdita di dati e con perdita di dati. Con la giusta combinazione di impostazioni, possono ridurre notevolmente le dimensioni del file di un'immagine. In questo modo non solo risparmi la larghezza di banda durante il caricamento delle immagini esterne, ma, una volta ottimizzate, le immagini verranno tradotte in stringhe codificate base64 molto più piccole per l'inserimento in linea in HTML, CSS e JavaScript. A proposito di codifica base64, abbiamo anche incorporato i file dei caratteri WOFF e SVG di Open Sans direttamente nel CSS utilizzando questa tecnica, il che ha comportato un numero ancora inferiore di richieste totali.
La scena 3D con fisica attivata
THREE.js è la libreria JavaScript 3D onnipresente per il web. Includi matematica 3D di basso livello e ottimizzazioni WebGL basate sull'hardware che consentono ai comuni mortali di creare facilmente scene 3D interattive ben illuminate e belle senza dover scrivere shader personalizzati o eseguire trasformazioni di matrici manuali. Physijs è un wrapper specifico per THREE.js di una popolare libreria di fisica C++ tradotta in JavaScript. Abbiamo sfruttato questa libreria per simulare il rotolamento, il salto e il rimbalzo della palla verso la sua destinazione in 3D.
Fin dall'inizio, ci siamo propositi non solo di rendere realistica l'esperienza fisica del lancio della palla, ma anche di fare in modo che gli oggetti nel gioco sembrassero reali. Ciò ha richiesto molte iterazioni per regolare la gravità complessiva della scena Physijs, la velocità della palla mentre rotola dal lancio del giocatore, la pendenza del salto della corsia e le proprietà di attrito e restituzione (elasticità) dei materiali della palla e della corsia. La combinazione di maggiore gravità e maggiore velocità ha dato vita a un'esperienza di gioco più realistica.
Lisciando
La maggior parte delle combinazioni di browser e schede video moderne dovrebbe sfruttare l'anti-aliasing nativo basato sull'hardware nell'ambiente WebGL, ma alcune non sono compatibili. Se l'anti-aliasing non funziona in modo nativo, tutti i bordi duri e contrastati nella scena THREE.js saranno frastagliati e brutti (almeno per i nostri occhi esigenti).
Fortunatamente esiste una soluzione: tramite uno snippet di codice, possiamo rilevare se la piattaforma supporta l'antialiasing in modo nativo. In caso affermativo, non c'è problema. In caso contrario, esistono una serie di shader di post-elaborazione forniti con THREE.js che possono aiutarci. Nello specifico, il filtro anti-aliasing FXAA. Se ridisegniamo la scena visualizzata a ogni frame con questo shader, in genere otteniamo linee e bordi molto più fluidi. Guarda la demo di seguito:
// Check for native platform antialias support via the THREE renderer
// from: http://codeflow.org/entries/2013/feb/22/how-to-write-portable-webgl/#antialiasing
var nativeAntialiasSupport = (renderer.context.getParameter(renderer.context.SAMPLES) == 0) ? false : true;
Controlli dei giochi basati sull'accelerometro
Gran parte della magia di Roll It è data dal gesto di rotazione della palla che il giocatore esegue con uno smartphone. I dispositivi mobili hanno accesso all'accelerometro all'interno del browser da un po' di tempo, ma come settore stiamo appena iniziando a esplorare il riconoscimento dei gesti basato sul movimento sul web. I dati forniti dall'accelerometro dello smartphone sono un po' limitati, ma con un po' di creatività possiamo creare nuove esperienze straordinarie.
Il rilevamento del gesto principale "inclinazione" di It's inizia con il monitoraggio dei 10 aggiornamenti dell'accelerometro più recenti provenienti dall'evento deviceorientation
della finestra. Sottraendo il valore dell'inclinazione precedente dal valore dell'inclinazione attuale, memorizziamo la delta dell'angolo tra gli eventi. Poi, sommando costantemente gli ultimi dieci delta angolari, possiamo rilevare la rotazione continua mentre lo smartphone si muove nello spazio. Quando lo smartphone supera una soglia di variazione dell'angolo di scansione, viene attivato un roll. Poi, trovando il delta di inclinazione singolo più grande in questo rilevamento, possiamo stimare una velocità per la palla. In Roll It, questa velocità viene normalizzata utilizzando i timestamp che colleghiamo a ogni aggiornamento dell'accelerometro. In questo modo, viene attenuata la velocità variabile con cui gli aggiornamenti dell'accelerometro vengono trasmessi in streaming nel browser su dispositivi diversi.
Comunicazione WebSocket
Una volta che il giocatore fa rotolare la palla con il telefono, viene inviato un messaggio dal telefono al laptop per lanciare la palla. Questo messaggio "roll" viene inviato tramite un oggetto dati JSON attraverso una connessione WebSocket tra le due macchine. I dati JSON sono di piccole dimensioni e consistono principalmente in un tipo di messaggio, nella velocità di lancio e nella direzione di mira.
{
"type": "device:ball-thrown",
"speed": 0.5,
"aim": 0.1
}
Tutte le comunicazioni tra il laptop e lo smartphone avvengono tramite piccoli messaggi JSON come questo. Ogni volta che il gioco aggiorna il proprio stato sul computer o l'utente inclina o tocca un pulsante sul telefono, viene trasmesso un messaggio WebSocket tra le macchine. Per mantenere questa comunicazione semplice e facile da gestire, i messaggi WebSocket vengono trasmessi utilizzando un unico punto di uscita da entrambi i browser. Al contrario, nel browser di ricezione è presente un unico punto di contatto, con un oggetto WebSocket che gestisce tutti i messaggi in entrata e in uscita su entrambe le estremità. Quando viene ricevuto un messaggio WebSocket, i dati JSON vengono ritrasmessi all'interno dell'app JavaScript utilizzando il metodo trigger()
di jQuery. A questo punto, i dati in entrata si comportano come qualsiasi altro evento DOM personalizzato e possono essere rilevati ed elaborati da qualsiasi altro oggetto dell'applicazione.
var websocket = new WebSocket(serverIPAddress);
// rebroadcast incoming WebSocket messages with a global event via jQuery
websocket.onmessage = function(e) {
if (e.data) {
var obj = JSON.parse(e.data);
$(document).trigger(data.type, obj);
}
};
// broadcast outgoing WebSocket messages by passing in a native .js object
var broadcast = function(obj) {
websocket.send(JSON.stringify(obj));
};
I server WebSocket di Roll It vengono creati dinamicamente quando due dispositivi vengono sincronizzati con un codice di gioco. Il backend di Roll It è stato creato sulla piattaforma Google Compute Engine e App Engine utilizzando Go.
Schermate del menu inclinate
Oltre ai messaggi WebSocket basati su eventi utilizzati durante il gameplay, i menu di Roll It vengono controllati inclinando lo smartphone e toccando un pulsante per confermare una selezione. Ciò richiede uno stream di dati sull'inclinazione più coerente trasmesso dallo smartphone al laptop. Per ridurre la larghezza di banda ed evitare di inviare aggiornamenti non necessari, questi messaggi vengono inviati solo se l'inclinazione del dispositivo è cambiata di più di un paio di gradi. Non ha senso inviare uno stream di dati sull'inclinazione se lo smartphone è appoggiato su un tavolo. Anche la velocità di trasmissione viene limitata: in Roll It non vengono inviati più di 15 messaggi WebSocket al secondo, anche se il dispositivo viene inclinato attivamente.
Una volta rilevati i valori di inclinazione sul computer, vengono interpolati nel tempo utilizzando requestAnimationFrame
per mantenere un'esperienza fluida. Il risultato finale è un menu in rotazione e una palla che rotola per indicare la selezione dell'utente. Quando lo smartphone invia i dati sull'inclinazione, questi elementi DOM vengono aggiornati in tempo reale ricalcolando una trasformazione CSS all'interno del ciclo requestAnimationFrame
. Il contenitore del menu ruota semplicemente, ma la palla sembra rotolare sul pavimento. Per ottenere questo effetto, abbiamo implementato alcune nozioni di trigonometria di base per mettere in relazione la coordinata x delle sfere con la loro rotazione. L'equazione semplice è: rotazioni = x / (diametro * π)
Conclusione
Roll It è un segno dei tempi. Tra i progetti open source che ne hanno supportato lo sviluppo, la potenza di elaborazione dei dispositivi sulle nostre scrivanie e nelle nostre tasche e lo stato del web come piattaforma, è un momento davvero entusiasmante e di trasformazione per essere connessi al web aperto. Solo pochi anni fa, gran parte di questa tecnologia esisteva solo in sistemi proprietari, non disponibili per l'utilizzo e la distribuzione senza costi. Oggi, le esperienze complesse possono essere realizzate con meno lavoro e più immaginazione, perché ogni giorno creiamo e condividiamo nuovi pezzi del puzzle. Dunque, cosa aspetti? Crea qualcosa di fantastico e condividilo con il mondo.