„Roll It“ wird erstellt

Justin Gitlin
Justin Gitlin

Roll It ist ein Chrome-Experiment, bei dem ein klassisches Spiel aus dem Vergnügungspark nur mit dem Browser auf Ihrem Smartphone und Computer neu interpretiert wird. Im Browser auf Ihrem Smartphone können Sie den Ball mit einem Wisch des Handgelenks ausrichten und losrollen lassen. Der Browser auf Ihrem Computer rendert die Echtzeitgrafiken der Roll It-Bahn mit WebGL und Canvas. Die beiden Geräte kommunizieren über Websockets. Keine Apps Keine Downloads Keine Tokens. Sie benötigen lediglich einen modernen Browser.

Unter der Leitung von Google Creative Lab hat Legwork die Nutzererfahrung, die Benutzeroberflächen und die Spielumgebung entwickelt und dann mit dem Entwicklungspartner Mode Set zusammengearbeitet, um Roll It zu erstellen. Im Laufe des Projekts gab es eine Reihe von einzigartigen Herausforderungen. In diesem Artikel werden einige der Techniken beschrieben, die wir verwendet haben, Tricks, die wir entdeckt haben, und Erkenntnisse, die wir bei der Entwicklung von „Roll It“ gewonnen haben.

3D-Workflow

Eine der Herausforderungen zu Beginn bestand darin, herauszufinden, wie 3D‑Modelle aus unserer Software am besten in ein webfähiges Dateiformat umgewandelt werden können. Nachdem die Assets in Cinema 4D erstellt wurden, wurden die Modelle vereinfacht und in Low-Polygon-Meshes umgewandelt. Jedem Mesh wurden bestimmte Polygonauswahl-Tags zugewiesen, um zwischen den Teilen des Objekts für die Färbung und Texturierung zu unterscheiden. Wir konnten sie dann als Collada 1.5-Datei (.dae) exportieren und in Blender, einem Open-Source-3D-Programm, importieren, um kompatible Dateien für three.js zu erstellen. Nachdem wir sichergestellt hatten, dass unsere Modelle korrekt importiert wurden, exportierten wir das Mesh als JSON-Datei und die Beleuchtung wurde mit Code angewendet. Hier sind die einzelnen Schritte im Detail:

Modellieren Sie das Objekt in C4D. Achten Sie darauf, dass die Netznormalen nach außen zeigen.
Modellieren Sie das Objekt in C4D. Achten Sie darauf, dass die Netznormalen nach außen zeigen.
Erstellen Sie mit dem Polygonauswahl-Tool Auswahl-Tags für die Bereiche, die Sie texturieren möchten. Wenden Sie Materialien auf jedes der Auswahl-Tags an.
Erstellen Sie mit dem Polygonauswahl-Tool Auswahl-Tags für die Bereiche, die Sie texturieren möchten. Wenden Sie Materialien auf jedes der Auswahl-Tags an.
Exportieren Sie das Mesh als COLLADA 1.5-Datei im DAE-Format.
Exportieren Sie das Mesh als COLLADA 1.5-Datei im DAE-Format.
Achten Sie darauf, dass die Option „2D-Geometrie exportieren“ aktiviert ist. Der Export von Dreiecken wird in 3D-Umgebungen auf der Codeseite in der Regel breiter unterstützt, hat aber den Nachteil, dass sich die Polygonanzahl verdoppelt. Je höher die Polygonanzahl, desto mehr belastet das Modell den Prozessor des Computers. Lassen Sie diese Option aktiviert, wenn die Leistung zu niedrig ist.
Achten Sie darauf, dass die Option „2D-Geometrie exportieren“ aktiviert ist. Der Export von Dreiecken wird in 3D-Umgebungen auf der Codeseite in der Regel breiter unterstützt, hat aber den Nachteil, dass sich die Polygonanzahl verdoppelt. Je höher die Polygonanzahl, desto mehr belastet das Modell den Prozessor des Computers. Lassen Sie diese Option daher aktiviert, wenn die Leistung zu gering ist.
Importieren Sie die Collada-Datei in Blender.
Importieren Sie die Collada-Datei in Blender.
Nach dem Import in Blender sehen Sie, dass auch Ihre Material- und Auswahl-Tags übernommen wurden.
Nach dem Import in Blender sehen Sie, dass auch Ihre Material- und Auswahl-Tags übernommen wurden.
Wählen Sie das Objekt aus und passen Sie die Materialien des Objekts nach Ihren Wünschen an.
Wählen Sie das Objekt aus und passen Sie die Materialien des Objekts nach Ihren Wünschen an.
Datei als three.js-Datei exportieren
Exportieren Sie die Datei als three.js-Datei für die WebGL-Kompatibilität.

Code schreiben

Roll It wurde mit Open-Source-Bibliotheken entwickelt und kann nativ in modernen Browsern ausgeführt werden. Mit Technologien wie WebGL und WebSockets nähert sich das Web Gaming- und Multimedia-Erlebnissen in Konsolenqualität. Die Entwicklung dieser Funktionen ist dank moderner Tools für die HTML-Entwicklung immer einfacher geworden.

Entwicklungsumgebung

Der Großteil des ursprünglichen Codes von Roll It wurde in CoffeeScript geschrieben – einer sauberen und prägnanten Sprache, die in gut formatiertes und linted JavaScript umgewandelt wird. CoffeeScript eignet sich dank seines hervorragenden Vererbungsmodells und der saubereren Bereichsverwaltung hervorragend für die objektorientierte Programmentwicklung. Das CSS wurde mit dem SASS geschrieben, das den Entwicklern eine Reihe hervorragender Tools zur Verbesserung und Verwaltung der Stylesheets eines Projekts bietet. Die Einrichtung dieser Systeme im Build-Prozess dauert etwas, aber der Aufwand lohnt sich auf jeden Fall, vor allem bei einem größeren Projekt wie Roll It. Wir haben einen Ruby on Rails-Server eingerichtet, um unsere Assets während der Entwicklung automatisch zu kompilieren. So wurden alle diese Kompilierungsschritte transparent.

Neben der Schaffung einer optimierten und komfortablen Codierungsumgebung haben wir Assets manuell optimiert, um Anfragen zu minimieren und die Website schneller zu laden. Wir haben jedes Bild mit mehreren Komprimierungsprogrammen bearbeitet: ImageOptim und ImageAlpha. Jedes Programm optimiert Bilder auf seine eigene Weise – ohne bzw. mit Verlust. Mit der richtigen Kombination von Einstellungen lässt sich die Dateigröße eines Bilds erheblich reduzieren. Dadurch wird nicht nur beim Laden externer Bilder Bandbreite gespart, sondern nach der Optimierung werden Ihre Bilder in viel kleinere Base64-codierte Strings umgewandelt, die dann inline in HTML, CSS und JavaScript eingebettet werden können. Apropos Base64-Codierung: Wir haben auch unsere Open Sans-WOFF- und SVG-Schriftdateien mit dieser Technik direkt in das CSS eingebettet, was zu noch weniger Anfragen insgesamt führte.

Die physikbasierte 3D-Szene

THREE.js ist die weit verbreitete 3D-JavaScript-Bibliothek für das Web. Es umfasst Low-Level-3D-Mathematik und hardwarebasierte WebGL-Optimierungen, mit denen auch Laien ganz einfach gut beleuchtete und schöne interaktive 3D-Szenen erstellen können, ohne benutzerdefinierte Shader schreiben oder manuelle Matrixtransformationen ausführen zu müssen. Physijs ist ein THREE.js-spezifischer Wrapper für eine beliebte C++-Physikbibliothek, die in JavaScript übersetzt wurde. Mit dieser Bibliothek haben wir das Rollen, Springen und Aufprallen des Balls in 3D simuliert.

Von Anfang an wollten wir nicht nur das Rollen des Balls realistisch gestalten, sondern auch dafür sorgen, dass die Objekte im Spiel echt wirken. Dazu mussten die Schwerkraft der Physijs-Szene, die Geschwindigkeit des Balls beim Rollen nach dem Wurf des Spielers, die Steigung des Sprungs der Bahn sowie die Reibungs- und Rückstelleigenschaften (Sprungkraft) des Balls und der Bahnmaterialien mehrmals angepasst werden. Die Kombination aus mehr Schwerkraft und mehr Geschwindigkeit führte zu einem realistischeren Spielerlebnis.

Glättung

Die meisten modernen Browser- und Grafikkartenkombinationen sollten natives hardwarebasiertes Anti-Aliasing in der WebGL-Umgebung nutzen, aber einige funktionieren nicht richtig. Wenn Anti-Aliasing nicht nativ funktioniert, sind alle harten und kontrastreichen Kanten in der THREE.js-Szene (zumindest für unsere kritischen Augen) gezackt und hässlich.

Glücklicherweise gibt es eine Lösung: Mit einem Code-Snippet können wir feststellen, ob die Plattform Anti-Aliasing nativ unterstützt. Wenn das der Fall ist, können wir loslegen. Andernfalls gibt es eine Reihe von Post-Processing-Shadern, die mit THREE.js geliefert werden und uns weiterhelfen können. Dabei handelt es sich um den Anti-Aliasing-Filter FXAA. Wenn wir die gerenderte Szene mit diesem Shader in jedem Frame neu zeichnen, erhalten wir in der Regel viel glattere Linien und Kanten. Demo unten ansehen:

// 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;

Beschleunigungsmesserbasierte Spielsteuerung

Der Reiz von Roll It liegt vor allem in der Geste, mit der die Spieler den Ball rollen. Mobilgeräte haben schon seit einiger Zeit Zugriff auf den Beschleunigungsmesser im Browser. Wir als Branche stehen jedoch erst am Anfang der Erforschung der bewegungsbasierten Gestenerkennung im Web. Wir sind etwas eingeschränkt durch die Daten, die der Beschleunigungsmesser des Smartphones liefert, aber mit ein wenig Kreativität können wir tolle neue Funktionen entwickeln.

Erkennen der Hauptgeste „Drehen“: Zuerst werden die 10 aktuellsten Beschleunigungsmesser-Updates erfasst, die vom deviceorientation-Ereignis des Fensters stammen. Wenn wir den vorherigen Neigungswert vom aktuellen Neigungswert abziehen, speichern wir das Winkeldelta zwischen den Ereignissen. Durch die ständige Addition der letzten zehn Winkeldeltas können wir dann eine kontinuierliche Drehung erkennen, wenn sich das Smartphone im Raum bewegt. Wenn das Smartphone einen Schwellenwert für die Änderung des Schwenkwinkels überschreitet, wird ein Schwenk ausgelöst. Wenn wir dann das größte einzelne Neigungsdelta in diesem Sweep ermitteln, können wir eine Geschwindigkeit für den Ball schätzen. In Roll It wird diese Geschwindigkeit anhand von Zeitstempeln normalisiert, die wir jedem Beschleunigungsmesser-Update zuordnen. So wird die variable Geschwindigkeit ausgeglichen, mit der Accelerometer-Updates auf verschiedenen Geräten in den Browser gestreamt werden.

WebSocket-Kommunikation

Sobald der Spieler den Ball mit seinem Smartphone rollt, wird eine Nachricht vom Smartphone an den Laptop gesendet, die ihn auffordert, den Ball zu starten. Diese „Roll“-Nachricht wird über ein JSON-Datenobjekt über eine WebSocket-Verbindung zwischen den beiden Maschinen gesendet. Die JSON-Daten sind klein und bestehen hauptsächlich aus einem Nachrichtentyp, der Wurfgeschwindigkeit und der Zielrichtung.

{
  "type": "device:ball-thrown",
  "speed": 0.5,
  "aim": 0.1
}

Die gesamte Kommunikation zwischen Laptop und Smartphone erfolgt über kleine JSON-Nachrichten wie diese. Jedes Mal, wenn das Spiel seinen Status auf dem Computer aktualisiert oder der Nutzer das Smartphone neigt oder auf eine Schaltfläche tippt, wird eine WebSocket-Nachricht zwischen den Maschinen übertragen. Um diese Kommunikation einfach und verwaltungsfreundlich zu gestalten, werden die WebSocket-Nachrichten über einen einzigen Ausgangspunkt aus einem der beiden Browser gesendet. Im empfangenden Browser gibt es dagegen einen einzigen Einstiegspunkt, wobei ein WebSocket-Objekt alle ein- und ausgehenden Nachrichten an beiden Enden verarbeitet. Wenn eine WebSocket-Nachricht empfangen wird, werden die JSON-Daten mit der trigger()-Methode von jQuery in der JavaScript-Anwendung noch einmal übertragen. An diesem Punkt verhalten sich die eingehenden Daten genau wie jedes andere benutzerdefinierte DOM-Ereignis und können von jedem anderen Objekt in der Anwendung abgerufen und verarbeitet werden.

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));
};

Die WebSocket-Server von Roll It werden „on-the-fly“ erstellt, wenn zwei Geräte mit einem Spielcode synchronisiert werden. Das Back-End für Roll It wurde mit Go auf der Google Compute Engine und der App Engine-Plattform erstellt.

Menübildschirme neigen

Neben den ereignisgesteuerten WebSocket-Nachrichten, die während des Spiels verwendet werden, werden die Menüs in Roll It durch Neigen des Smartphones und Tippen auf eine Schaltfläche zur Bestätigung einer Auswahl gesteuert. Dazu ist ein gleichmäßigerer Stream von Neigungsdaten erforderlich, der vom Smartphone an den Laptop übertragen wird. Um die Bandbreite zu reduzieren und unnötige Aktualisierungen zu vermeiden, werden diese Nachrichten nur gesendet, wenn sich die Neigung des Geräts um mehr als ein paar Grad geändert hat. Es hat keinen Sinn, einen Stream von Neigungsdaten zu senden, wenn das Smartphone flach auf einem Tisch liegt. Die Übertragungsrate wird ebenfalls gedrosselt. In Roll It werden nicht mehr als 15 WebSocket-Nachrichten pro Sekunde gesendet, auch wenn das Gerät aktiv geneigt wird.

Sobald die Neigungswerte auf dem Computer erfasst wurden, werden sie mit requestAnimationFrame über die Zeit interpoliert, um eine flüssige Bedienung zu ermöglichen. Das Endergebnis ist ein rotierendes Menü und ein rollender Ball, der die Auswahl des Nutzers anzeigt. Wenn das Smartphone Neigungsdaten sendet, werden diese DOM-Elemente in Echtzeit aktualisiert, indem eine CSS-Transformation innerhalb der requestAnimationFrame-Schleife neu berechnet wird. Der Container des Menüs dreht sich einfach, aber der Ball scheint über den Boden zu rollen. Um diesen Effekt zu erzielen, implementieren wir einige grundlegende trigonometrische Funktionen, um die X-Koordinate des Balls mit seiner Rotation in Beziehung zu setzen. Die einfache Gleichung lautet: Umdrehungen = x ÷ (Durchmesser × π)

Zusammenfassung

Roll It ist ein Zeichen der Zeit. Die Open-Source-Projekte, die die Entwicklung vorangetrieben haben, die Rechenleistung der Geräte auf unseren Schreibtischen und in unseren Hosentaschen sowie der aktuelle Stand des Webs als Plattform – es ist eine wirklich spannende und transformative Zeit, um im offenen Web verbunden zu sein. Vor wenigen Jahren gab es einen Großteil dieser Technologie nur in proprietären Systemen, die nicht frei verwendet und verteilt werden konnten. Heutzutage können komplexe Erlebnisse mit weniger Arbeit und mehr Vorstellungskraft realisiert werden, da wir jeden Tag neue Puzzleteile erstellen und teilen. Worauf warten Sie noch? Erstelle etwas Tolles und teile es mit der Welt!

Roll it-Logo