Création du Roll It

Justin Gitlin
Justin Gitlin

Roll It est une expérience Chrome qui réinvente un jeu de promenade classique en utilisant uniquement le navigateur de votre téléphone et de votre ordinateur. Le navigateur de votre téléphone vous permet de viser et de faire rouler la balle d'un simple mouvement du poignet, tandis que le navigateur de votre ordinateur affiche les graphiques en temps réel de l'allée "Roll It" avec WebGL et Canvas. Les deux appareils communiquent via Websockets. Aucune appli. Aucun téléchargement. Aucun jeton. Il vous suffit d'un navigateur récent.

Sous la direction de Google Creative Lab, Legwork a développé l'expérience utilisateur, les interfaces et l'environnement de jeu, puis s'est associé à Mode Set, son partenaire de développement, pour concevoir Roll It. Au cours de la durée du projet, un certain nombre de défis uniques se sont produits. Cet article passe en revue quelques-unes des techniques que nous avons utilisées, des astuces que nous avons découvertes et des leçons que nous avons tirées de notre expérience.

Workflow 3D

Au début, l'une des difficultés consistait à trouver le meilleur moyen de transférer les modèles 3D de notre logiciel dans un format de fichier compatible avec le Web. Après avoir créé les éléments dans Cinema 4D, les modèles ont été simplifiés et convertis en maillages à faible polygone. Chaque maillage a reçu certains tags de sélection de polygones pour différencier les parties de l'objet à des fins de coloration et d'application de textures. Nous avons ensuite pu exporter un fichier Collada 1.5 (.dae) et l'importer dans Blender, un programme 3D Open Source, afin de créer des fichiers compatibles avec three.js. Après avoir vérifié que nos modèles avaient été importés correctement, nous avons exporté le maillage en tant que fichier JSON et l'éclairage a été appliqué à l'aide de code. Voici une description plus détaillée de la procédure que nous avons suivie:

Modélisez l'objet dans C4D. Veillez à ce que les points normaux de la grille soient orientés vers l'extérieur.
Modéliser l'objet dans C4D. Veillez à ce que les points normaux de la grille soient orientés vers l'extérieur.
À l'aide de l'outil de sélection de polygone, créez des tags de sélection pour les zones spécifiques auxquelles vous souhaitez appliquer des textures. Appliquez les supports à chacun des tags de sélection.
À l'aide de l'outil de sélection de polygones, créez des tags de sélection pour les zones spécifiques auxquelles vous souhaitez appliquer une texture. Appliquez les supports à chacun des tags de sélection.
Exportez votre maillage en tant que fichier.dae COLLADA 1 .5.
Exportez votre maillage en tant que fichier.dae COLLADA 1 .5.
Vérifiez que la case "Exporter les géométries 2D" est cochée. Du côté du code, l'exportation de triangles est généralement plus possible dans les environnements 3D, mais l'inconvénient est de doubler le nombre de polygones. Plus le nombre de polygones est élevé, plus le modèle est soumis à une charge de travail importante pour le processeur de l'ordinateur. Laissez cette case cochée si vous constatez que les performances sont lentes.
Vérifiez que la case "Exporter la géométrie 2D" est cochée. Du côté du code, l'exportation de triangles est généralement plus possible dans les environnements 3D, mais l'inconvénient est de doubler le nombre de polygones. Plus le nombre de polygones est élevé, plus le modèle est soumis à une charge de travail importante pour le processeur de l'ordinateur. Laissez cette case cochée si vous constatez que les performances sont lentes.
Importez le fichier Collada dans Blender.
Importez le fichier Collada dans Blender.
Une fois importés dans le mixeur, vous constaterez que vos matériaux et vos tags de sélection ont également été transférés.
Une fois l'importation terminée dans le mixeur, vous constaterez que vos matériaux et vos tags de sélection ont également été transférés.
Sélectionnez votre objet et ajustez les matériaux de l'objet en fonction de vos préférences.
Sélectionnez votre objet et ajustez ses matériaux selon vos préférences.
Exporter le fichier au format three.js
Exportez le fichier au format three.js pour assurer la compatibilité avec WebGL.

Écrire le code

Roll It a été développé avec des bibliothèques Open Source et s'exécute de manière native dans les navigateurs modernes. Avec des technologies telles que WebGL et WebSockets, le Web est à la pointe des expériences multimédias et des jeux de qualité sur console. La facilité et le confort dont les développeurs peuvent bénéficier pour créer ces expériences ont progressé à mesure que des outils plus modernes sont disponibles pour le développement HTML.

L'environnement de développement

La majeure partie du code d'origine de Roll It a été écrit avec CoffeeScript, un langage clair et concis qui se transcompile en JavaScript bien formé et linté. CoffeeScript se distingue par son excellent modèle d'héritage et une gestion plus claire des champs d'application. Le CSS a été écrit à l'aide du framework SASS, qui offre au développeur un certain nombre d'excellents outils pour améliorer et gérer les feuilles de style d'un projet. L'ajout de ces systèmes au processus de compilation prend un peu de temps, mais le gain en vaut vraiment la peine, surtout pour un projet plus vaste comme Roll It. Nous avons configuré un serveur Ruby on Rails afin de compiler automatiquement nos éléments pendant le développement. Toutes ces étapes de compilation sont ainsi devenues transparentes.

Au-delà de la création d'un environnement de codage simplifié et confortable, nous avons optimisé manuellement les composants pour minimiser le nombre de demandes et accélérer le chargement du site. Nous avons fait appel à deux programmes de compression pour chaque image : ImageOptim et ImageAlpha. Chaque programme optimise les images à leur manière : avec et sans perte, respectivement. En combinant les paramètres appropriés, elles peuvent réduire considérablement la taille du fichier d'une image. Cela permet non seulement d'économiser de la bande passante lors du chargement d'images externes, mais aussi une fois optimisées, vos images seront converties en chaînes encodées en base64 bien plus petites pour une intégration intégrée en HTML, CSS et JavaScript. Pour ce qui est de l'encodage en base64, nous avons également intégré nos fichiers de polices WOFF et SVG Open Sans directement dans le CSS en utilisant cette technique, ce qui a entraîné une diminution du nombre total de requêtes.

La scène 3D basée sur les lois de la physique

THREE.js est la bibliothèque JavaScript 3D omniprésente sur le Web. Elle inclut des optimisations mathématiques 3D de bas niveau et des optimisations WebGL matérielles qui permettent à de simples mortels de créer facilement de magnifiques scènes 3D interactives bien éclairées, sans avoir à écrire de nuanceurs personnalisés ni à effectuer des transformations matricielles manuelles. Physijs est un wrapper spécifique à THREE.js pour une bibliothèque de physique C++ populaire qui a été traduite en JavaScript. Nous avons utilisé cette bibliothèque pour simuler le roulement de la balle, le saut et le rebond vers sa destination en 3D.

Dès le départ, nous avons entrepris de rendre l'expérience physique du jeu réaliste, mais aussi de rendre les objets réels. Cela a nécessité de nombreuses itérations d'ajustement de la gravité globale de la scène de Physijs, de la vitesse de la balle lorsqu'elle roule à partir du lancer du joueur, de la pente du saut de la voie et des propriétés de frottement et de restitution (rebond) des matériaux de la balle et de la voie. L'allongement de la gravité et de la vitesse a donné lieu à une expérience de jeu plus réaliste.

Lisser

La plupart des combinaisons de navigateurs modernes et de cartes vidéo devraient bénéficier de l'anticrénelage basé sur le matériel natif dans l'environnement WebGL, mais certaines d'entre elles ne fonctionneront pas correctement. Si l'anticrénelage ne fonctionne pas en mode natif, les bords durs et contrastés de la scène THREE.js seront irréguliers et moches (du moins pour nos yeux avertis).

Heureusement, il existe une solution: un extrait de code nous permet de détecter si la plate-forme accepte nativement l'anticrénelage. Si tel n'est pas le cas, une série de nuanceurs de post-traitement, fournis avec THREE.js, peuvent nous aider. à savoir le filtre d'anticrénelage FXAA. En redessinant chaque image à l'aide de ce nuanceur, nous obtenons généralement un aspect beaucoup plus fluide des lignes et des bords. Consultez la démonstration ci-dessous:

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

Commandes de jeu basées sur l'accéléromètre

La magie opère, en grande partie, par le geste de roulement que le joueur effectue avec son téléphone. Depuis un certain temps déjà, l'accéléromètre du navigateur est accessible sur les appareils mobiles, mais notre secteur commence tout juste à explorer la reconnaissance des gestes basée sur les mouvements sur le Web. Nous sommes un peu limités par les données fournies par l'accéléromètre du téléphone, mais avec un peu de créativité, nous pouvons proposer de nouvelles expériences exceptionnelles.

La détection du geste de "roulis " principal commence par le suivi des 10 dernières mises à jour de l'accéléromètre issues de l'événement deviceorientation de la fenêtre. En soustrayant la valeur d'inclinaison précédente de la valeur d'inclinaison actuelle, nous stockons le delta de l'angle entre les événements. Ensuite, en additionnant en permanence les 10 derniers angles de delta, nous pouvons détecter une rotation continue lorsque le téléphone se déplace dans l'espace. Lorsque le téléphone atteint un seuil de changement d'angle de balayage, un roulis est déclenché. Ensuite, en déterminant le plus grand delta d'inclinaison lors de ce balayage, nous pouvons estimer la vitesse de la balle. Dans "Roll It", cette vitesse est normalisée à l'aide des codes temporels que nous associons à chaque mise à jour de l'accéléromètre. Cela permet de lisser la vitesse variable des mises à jour de l'accéléromètre dans le navigateur en fonction de l'appareil.

Communication WebSockets

Lorsque le joueur fait rouler la balle avec son téléphone, un message est envoyé du téléphone à l'ordinateur portable pour lui demander de lancer la balle. Ce message est envoyé via un objet de données JSON via une connexion WebSocket entre les deux machines. Les données JSON sont de petite taille. Elles sont principalement constituées d'un type de message, d'une vitesse de lancement et d'une direction de visée.

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

Toutes les communications entre l'ordinateur portable et le téléphone s'effectuent via de petits messages JSON comme celui-ci. Chaque fois que le jeu met à jour son état sur le bureau, ou que l'utilisateur incline ou appuie sur un bouton du téléphone, un message WebSocket est transmis entre les machines. Pour que cette communication reste simple et facile à gérer, les messages WebSockets sont diffusés à l'aide d'un seul point de sortie depuis l'un ou l'autre navigateur. À l'inverse, le navigateur de réception ne comporte qu'un seul point d'entrée, et un objet WebSocket gère tous les messages entrants et sortants aux deux extrémités. Lorsqu'un message WebSocket est reçu, les données JSON sont rediffusées dans l'application JavaScript à l'aide de la méthode trigger() de jQuery. À ce stade, les données entrantes se comportent comme n'importe quel autre événement DOM personnalisé. Elles peuvent être récupérées et traitées par n'importe quel autre objet de l'application.

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

Ses serveurs WebSocket sont créés à la volée lorsque deux appareils sont synchronisés avec un code de jeu. Le backend de Roll It a été créé sur les plates-formes Google Compute Engine et App Engine à l'aide de Go.

Écrans de menu inclinables

Au-delà des messages WebSocket basés sur les événements utilisés pendant le jeu, les menus de "Roll It" peuvent être contrôlés en inclinant le téléphone et en appuyant sur un bouton pour confirmer une sélection. Cela nécessite un flux plus constant de données d'inclinaison transmises du téléphone à l'ordinateur portable. Afin de réduire la bande passante et d'éviter l'envoi de mises à jour inutiles, ces messages ne sont envoyés que si l'inclinaison de l'appareil a changé de plus de quelques degrés. Il n'est pas utile d'envoyer un flux de données d'inclinaison si le téléphone est posé à plat sur une table. La vitesse de transmission est également limitée : pas plus de 15 messages WebSockets sont envoyés par seconde avec la fonctionnalité "Roll It", même si l'appareil est incliné.

Une fois que les valeurs d'inclinaison ont été détectées par l'ordinateur, elles sont interpolées au fil du temps à l'aide de requestAnimationFrame pour maintenir une sensation de fluidité. Le résultat final est un menu rotatif et une boule qui roule pour indiquer la sélection de l'utilisateur. Lorsque le téléphone envoie des données d'inclinaison, ces éléments DOM sont mis à jour en temps réel en recalculant une transformation CSS dans la boucle requestAnimationFrame. Le conteneur du menu tourne simplement, mais la balle semble rouler sur le sol. Pour obtenir cet effet, nous allons implémenter une trigonométrie de base pour relier les coordonnées X des balles à leur rotation. L'équation simple est la suivante: rotations = x / (diamètre * π)

Conclusion

"Roll It", c'est le signe des temps. Entre les projets Open Source qui ont stimulé son développement, la puissance de traitement des appareils sur nos bureaux et dans nos poches, et l'état du Web en tant que plate-forme, il s'agit d'une période passionnante et révolutionnaire de se connecter au Web ouvert. Il y a à peine quelques années, une grande partie de cette technologie n'existait que dans des systèmes propriétaires, inutilisables et distribués librement. Aujourd'hui, il est possible de concrétiser des expériences complexes avec moins de travail et plus d'imagination, car nous créons et partageons chaque jour de nouvelles pièces du puzzle. Alors, n'attendez plus ! Construisez de belles choses et partagez-les avec le monde entier !

Logo Roll It