Essayer en direct À propos de ce projet
Playroom est une salle d’arcade de salon qui tourne dans le navigateur. La page s’ouvre sur un bureau de jeu façon 1989 — un écran CRT, une console, une manette et une cartouche Snake déjà insérée — que l’on peut faire pivoter et examiner ; un clic sur la console ou sur POWER ON fait avancer la caméra vers l’écran, traverser le tube et atterrir dans une bibliothèque de trois cartouches.
Les trois jeux sont des créations originales de Playroom : Snake consiste à enchaîner les bouchées en rythme, Breakout apporte trois niveaux de briques et des bonus, et Blocks rend l’empilement prévisible grâce à un fantôme d’atterrissage et des sacs de sept pièces. Pas de compte, pas de mises à jour, pas de sauvegardes — les meilleurs scores restent dans votre navigateur, et la musique comme les effets se coupent d’un seul bouton.
L’ensemble du projet ne dépend que de Three.js et de Vite, sans backend ni variables d’environnement ; six modèles de matériel GLB et un unique décalque à la marque faciale Tripo constituent toute la liste des ressources. Quand WebGL n’est pas disponible, un menu texte prend le relais et les jeux restent entièrement jouables.
Points forts
- Faites glisser pour tourner autour de tout le salon — écran CRT, console, manette et cartouche —, puis cliquez sur la console ou sur POWER ON : la caméra avance vers l’écran et traverse le CRT jusqu’à la bibliothèque de cartouches.
- Trois cartouches, trois jeux originaux : Snake, avec un enchaînement 5× en cinq secondes et un fruit doré à 50 points ; Breakout, avec trois niveaux de briques et les bonus W (raquette élargie) et 3 (triple balle) ; Blocks, avec des sacs de sept pièces, un fantôme d’atterrissage et des bonus de combo.
- Flèches / WASD et Espace sur ordinateur, P pour la pause et Échap pour quitter, commandes tactiles sur mobile ; les meilleurs scores ne vivent que dans votre propre navigateur.
- Chaque jeu possède sa propre boucle chiptune et ses effets sonores, et les menus diffusent le morceau « Trip Of Your Smile » (CC BY 4.0) ; si WebGL n’est pas disponible, l’arcade se rabat sur des boutons texte et reste jouable.
Analyse technique
Ressources 3D · Six pièces de matériel GLB reliées à l’exécution
L’écran CRT, la console, la manette et les trois cartouches sont livrés sous forme de six fichiers GLB (exportés avec le GLTFExporter de Three.js, en low-poly de 128 à 384 triangles chacun). GLTFLoader les charge en parallèle et chaque instance est un clone profond : les décalages de centrage issus de l’export sont remis à zéro, les matériaux sont clonés par instance, et chaque mesh projette et reçoit des ombres. La plaque d’étiquette de la cartouche est retrouvée grâce à son décalage local exporté, nommée cartridge-label et remappée sur une texture de couverture peinte dans un Canvas ; la mascotte en pixels est riggée à partir de nœuds nommés — mascot-body, les deux bras, l’antenne et un décalque de logo portant la marque faciale Tripo, avec tone mapping et écriture de profondeur désactivés pour que le décalque plat reste net.
La couche d’assets conserve aussi un emplacement d’échange : pointez le champ controller de public/models/manifest.json vers n’importe quel GLB et fitProp le met à l’échelle d’après sa boîte englobante à 2,54 unités de large, le pose au sol, le centre et reprend la position de la manette d’origine — une manette personnalisée (générée avec Tripo, par exemple) s’insère sans toucher au code.
Écran et étiquettes · Des textures Canvas comme interface
La scène ne charge aucune texture externe. La face du CRT est une CanvasTexture de 1024×700 : l’écran de veille (PLAYROOM SYSTEM / PLAYER ONE / PRESS START) est dessiné image par image sur un contexte 2D et sert à la fois de map et d’emissiveMap pour faire luire le tube. Chaque couverture de cartouche est un canvas de 640×610 à part, peint à la volée d’après la couleur, l’encre, le numéro et l’accroche du jeu dans le catalogue — pixel art et lettrage du titre compris.
À l’allumage, un contrôleur de cycle de vie de l’écran remplace le matériau par une texture de flux de données pendant que la caméra revient face au tube le long d’une trajectoire sphérique autour du centre de l’écran, avance et coupe vers la bibliothèque en traversant le verre ; avec prefers-reduced-motion, tout le mouvement est ignoré au profit d’une bascule directe.
Interaction · Gestes du pointeur, sélection par raycast et orbite cinématique
Dans la vue du bureau, une même séquence du pointeur sert à la fois de glissement d’orbite et de clic : le contrôleur de gestes enregistre theta / phi à l’appui, considère tout mouvement au-delà d’un seuil comme un glissement et le reste comme un clic. Les impacts sont résolus par un Raycaster — sur le bureau, l’ensemble du dispositif fait office de bouton d’allumage ; dans la bibliothèque, l’impact remonte la chaîne des parents jusqu’au nœud portant un gameId. Au relâchement, l’orbite ne se fige jamais : un contrôleur cinématique fond le décalage manuel dans un lent balancement automatique.
Survoler ou cibler une cartouche la soulève de 0,24, l’incline vers l’avant avec un léger roulis et fait passer la mascotte en pixels à la pose de ce jeu, tandis que chaque cartouche oscille sur sa propre phase sinusoïdale. Chaque interpolation de la boucle de rendu utilise l’easing indépendant de la fréquence d’images 1 − e^(−5·dt), si bien que les images lentes ne provoquent jamais de saut.
Jeux et audio · Sessions 2D autonomes et son synthétisé
Les trois jeux sont de purs modules de logique (create / step / input) ; une couche de session les dessine sur un canvas 2D autonome — 480×480 pour Snake et Breakout, 300×540 pour Blocks. requestAnimationFrame n’est planifié que pendant la partie, la pause arrête donc littéralement les images, et un plafond de 250 ms par pas empêche le tunneling après un changement d’onglet. Les événements de jeu (manger, brique, ligne, bonus, niveau) alimentent une couche d’effets de particules et se réduisent par priorité à un seul signal sonore.
Tout l’audio est synthétisé en direct avec des oscillateurs Web Audio : une mélodie chiptune de 16 pas par jeu (82–120 BPM) et une vingtaine de signaux construits à partir de glissements de fréquence et d’enveloppes, plafonnés à 64 voix. Le morceau du menu est un enregistrement CC BY 4.0 qui se rabat sur la boucle synthétisée si le téléchargement échoue ; le son se coupe quand l’onglet est masqué et le contexte ne se déverrouille qu’après le premier clic. Les meilleurs scores vont dans localStorage et se replient en mémoire si le stockage est refusé — une sauvegarde échouée n’interrompt jamais une partie.


