Un écran ILI9341 de 2,4 pouces, un pad directionnel fait de quatre boutons poussoirs et deux boutons supplémentaires pour A et B : voilà une console de jeu portable, et un ESP32 est largement suffisant pour la faire tourner. Nous avons créé cinq jeux pour cette configuration, puis un sixième, Skythread, pour une console portable plus grande avec un stick analogique, et nous avons placé les six dans la galerie d’exemples de Velxio. Chacun est un sketch Arduino, et chacun s’exécute dans votre navigateur : appuyez sur Run et jouez, sans carte, sans écran, sans soudure.
| Jeu | Carte | Type de jeu | Fréquence d’images dans Velxio |
|---|---|---|---|
| ESP32 Doom | ESP32 DevKit | jeu de tir à la première personne | environ 18 FPS |
| Sky Duel | Seeed XIAO ESP32-S3 | combat aérien en vue de côté | environ 29 FPS |
| XIAO Quest | Seeed XIAO ESP32-S3 | jeu de rôle en vue de dessus | environ 32 FPS |
| Gear Hop | Seeed XIAO ESP32-S3 | jeu de plateforme à défilement latéral | environ 27 FPS |
| Circuit Defense | Seeed XIAO ESP32-S3 | tower defense | environ 31 FPS |
| Skythread | Seeed XIAO ESP32-S3 Sense | vol en 3D au-dessus d’un paysage généré | environ 20 FPS |
Le premier, Doom, est arrivé en premier et tourne sur l’ESP32 classique. Les quatre suivants tournent sur le Seeed Studio XIAO ESP32-S3, la carte de la taille d’un pouce de notre partenaire Seeed, et ils partagent un même petit moteur. Le dernier, Skythread, tourne sur le XIAO ESP32-S3 Sense, la même puce avec 8 Mo de PSRAM, dont il a besoin pour garder tout un paysage en mémoire. Cet article explique comment chaque jeu se joue et comment il fonctionne à l’intérieur.
Comment y jouer dans Velxio
- Ouvrez n’importe quel jeu du tableau ci-dessus. Le sketch, les bibliothèques et le circuit se chargent ensemble.
- Appuyez sur Run. Velxio compile le sketch et le démarre. La première compilation d’un sketch prend jusqu’à une minute ; ensuite, elle provient du cache de compilation.
- Chaque jeu commence par une démo en mode attractif qui se joue toute seule. Appuyez sur n’importe quelle touche ou bouton pour prendre la main.
- Jouez au clavier : les flèches sont le pad directionnel, Z est A et X est B. Chaque bouton sur le canevas affiche sa touche dans une petite touche de clavier. Vous pouvez aussi cliquer sur les boutons à la souris, et maintenir un clic pour garder le bouton enfoncé. Skythread a un stick analogique et plus de boutons ; ses commandes sont décrites dans sa propre section ci-dessous.
- Ouvrez le moniteur Serial pour suivre le journal du jeu : une ligne
STATavec la fréquence d’images, et une ligneEVTpour chaque élimination, niveau, objet ramassé et mort. Skythread affiche sa propre ligne toutes les deux secondes, avec la fréquence d’images, le temps de dessin et d’envoi de chaque image, et le score.
N’importe quel bouton poussoir dans Velxio peut être piloté au clavier, pas seulement ceux-ci. Faites un clic droit sur un bouton et utilisez la carte Keyboard control : cliquez dessus, appuyez sur une touche, et à partir de là, maintenir cette touche enfonce le bouton pendant que la simulation tourne.
Le simulateur exécute le firmware lui-même, compilé pour la puce réelle : Velxio émule l’ESP32 et l’ESP32-S3 instruction par instruction, dans votre navigateur, et dessine tout ce que le sketch envoie à l’ILI9341.
La console portable

Le XIAO n’a que 11 broches GPIO, et un écran plus six boutons en demandent douze. L’astuce est que l’écran n’a pas besoin de deux de ses lignes habituelles : rien n’est jamais relu depuis l’écran, donc MISO reste non connectée, et sa broche de reset est reliée au 3,3 V pour qu’il se réinitialise avec la carte. Cela laisse exactement assez de broches.
| Broche XIAO | Va vers | Broche XIAO | Va vers | |
|---|---|---|---|---|
| D8 | écran SCK | D0 | pad directionnel HAUT | |
| D10 | écran MOSI | D1 | pad directionnel BAS | |
| D7 | écran CS | D2 | pad directionnel GAUCHE | |
| D9 | écran D/C | D3 | pad directionnel DROITE | |
| 3V3 | écran VCC, LED et RST | D4 | A | |
| GND | écran GND, tous les boutons | D5 | B |
Chaque bouton relie sa broche à la masse. Le sketch active les résistances de tirage internes de la puce avec pinMode(pin, INPUT_PULLUP), donc une broche lit HIGH quand le bouton est relâché et LOW quand il est enfoncé. Aucune résistance n’est nécessaire, ni sur le canevas ni sur une vraie plaque de prototypage. Doom utilise la même idée sur le plus grand ESP32 DevKit, avec ses propres broches (elles sont listées dans sa section ci-dessous).
Pourquoi le XIAO ESP32-S3
Les quatre jeux XIAO dessinent toute l’image en mémoire d’abord, puis l’envoient à l’écran d’un seul coup. Une image de 320 x 240 à deux octets par pixel fait 153 600 octets, et elle doit tenir dans un seul bloc continu de RAM.
C’est là que les deux puces diffèrent. Nous avons affiché le plus grand bloc libre depuis un sketch sur chacune : 110 592 octets sur l’ESP32 classique et 278 528 octets sur l’ESP32-S3. Le S3 peut contenir toute l’image avec de la place à revendre ; l’ESP32 classique ne le peut pas, ce qui explique pourquoi Doom dessine son image une colonne à la fois (nous y revenons plus bas).
Le S3 est aussi le plus rapide des deux dans le simulateur. Avec le même benchmark de framebuffer sur les deux cartes, le moteur intégré au navigateur de Velxio exécutait l’ESP32 à 81 à 90 millions d’instructions par seconde et l’ESP32-S3 à 96 à 106 millions, et le S3 produisait 33 images complètes par seconde contre 31 pour l’ESP32.
Un moteur pour quatre jeux
Les quatre sketches XIAO commencent par les mêmes 200 lignes : le moteur. Il gère le framebuffer, les boutons, une poignée de fonctions de dessin et la boucle d’images.

Dessiner en RAM signifie que l’ordre n’a pas d’importance. Un jeu peut peindre le ciel, puis les collines, puis les avions, puis les explosions par-dessus, et l’écran ne voit jamais que l’image terminée, donc rien ne scintille. L’envoyer se fait en trois appels à la bibliothèque Adafruit ILI9341 :
static void present() {
tft.startWrite();
tft.setAddrWindow(0, 0, SCR_W, SCR_H); // the whole 320 x 240 screen
tft.writePixels(fb, SCR_W * SCR_H); // 153,600 bytes in one burst
tft.endWrite();
}
À 40 MHz, ces 153 600 octets prennent environ 31 ms sur les fils SPI, donc le transfert seul fixe le plafond près de 30 images par seconde. Le reste de l’image, la logique du jeu et le dessin, doit tenir dans ce qui reste, ce qui explique pourquoi les fonctions de dessin sont simples : rectangles remplis, lignes, cercles, texte dans la police 5 x 7 fournie avec Adafruit GFX, et sprites.
Les sprites sont écrits sous forme de texte, un caractère par pixel, avec . pour les pixels transparents et une palette de 128 entrées pour le reste. Voici le robot de Gear Hop :
"........a.......",
"....mmmmmmmm....",
"...mMMMMMMMMm...",
"...mMllMMllMm...", // l = the eyes, light cyan
"...mMllMMllMm...",
"...mMMMMMMMMm...",
"....mmmrrmmm....", // r = the red mouth
Rien dans ces jeux ne provient d’un fichier image. Les tuiles de la carte, les textures et les effets sont dessinés par le code en RAM au démarrage de la carte, donc chaque sketch est du texte brut que vous pouvez lire et modifier dans l’éditeur.
Sky Duel : un combat aérien avec un modèle de vol
Vous pilotez un biplan au-dessus d’un monde large de quatre écrans qui se répète : franchissez le bord droit et vous réapparaissez à gauche. Un escadron rouge vous traque, des canons antiaériens et des camions attendent au sol, et chaque vague apporte un avion ennemi de plus.
Comment jouer. Pointez la croix directionnelle là où vous voulez voler, diagonales comprises ; l’avion tourne vers cette direction. Maintenez A pour les mitrailleuses et appuyez sur B pour larguer une bombe (six par vague). Les bombes sont le seul moyen de détruire les cibles au sol. Le radar en haut montre le monde entier, ce qui vous permet de repérer les avions hors écran.
Comment ça marche. L’avion ne se déplace pas à vitesse fixe. À chaque image, le sketch exécute un petit modèle de vol :

La vitesse dérive vers une valeur de croisière, mais monter coûte de la vitesse et piquer en fait gagner, proportionnellement à l’angle. Tirez tout droit vers le haut trop longtemps et l’avion passe sous la vitesse de décrochage : le nez tombe vers le sol de lui-même, et vous devez piquer pour reprendre le vol. Les pilotes ennemis suivent le même modèle, avec le même décrochage, ce qui en fait un combat aérien plutôt qu’un stand de tir.
L’avion est un seul sprite de 16 x 16 orienté vers la droite. Au démarrage, le sketch le fait pivoter en 32 caps et les stocke tous, en miroir pour ceux qui pointent vers la gauche afin que l’avion ne vole pas à l’envers. Dessiner un avion n’est alors qu’une lecture de table, agrandie deux fois à l’écran. Les ennemis se dirigent vers un point juste devant vous, tirent quand vous êtes devant leurs canons, et s’écartent après un passage rapproché pour ne pas vous percuter.
XIAO Quest : un petit RPG
Un héros, un village, une forêt et une grotte. L’ancien près de la fontaine vous raconte que le Roi de l’Ombre a emporté le cristal du village dans la vieille grotte, et vous donne la clé de la porte qui bloque le passage. Dans la forêt et la grotte, des monstres attaquent et vous les combattez au tour par tour.
Comment jouer. Marchez avec la croix directionnelle. A parle aux gens, lit les panneaux, ouvre les coffres et confirme ; B affiche vos statistiques et vos objets. La fontaine vous soigne, le marchand vend des potions pour 10 pièces d’or, et trois coffres contiennent deux potions, une épée de fer et un anneau d’argent. En combat, choisissez avec la croix directionnelle et confirmez avec A : attaquer, lancer une boule de feu (3 PM, dégâts doublés, ignore la défense), boire une potion ou fuir.
Comment ça marche. Le jeu est une petite machine à états. Chaque état a sa propre gestion des entrées et son propre affichage, et voici les événements qui le font passer de l’un à l’autre :

Les trois cartes font 20 x 14 tuiles de 16 pixels, écrites dans le sketch sous forme de chaînes, un caractère par tuile : # est un arbre, ~ de l’eau, = un chemin, K la porte verrouillée. Le héros se déplace d’une tuile à la fois et glisse entre les tuiles en 0,16 seconde, ce qui rend le mouvement fluide tout en gardant des collisions simples : un pas est autorisé ou il ne l’est pas.
Les combats utilisent de petites formules en nombres entiers. Une attaque inflige votre attaque plus un jet de 0 à 3, moins la défense de l’ennemi. L’expérience apporte des niveaux, et chaque niveau ajoute des points de vie, de magie, d’attaque et de défense. La grotte est sombre : après avoir dessiné la carte, le sketch atténue chaque pixel situé entre 50 et 70 pixels du héros à la moitié de sa luminosité et tout ce qui est plus loin au quart, si bien que vous portez une lanterne. Mesurer la distance de chaque pixel faisait chuter la fréquence d’images d’environ 27 à 16. En la calculant une fois par ligne à la place, sous forme d’une portion éclairée, d’une portion atténuée et d’un reste sombre, on remonte à environ 22.
Gear Hop : un jeu de plateforme
Un petit robot traverse deux niveaux en ramassant des engrenages. Des scarabées marchent au sol, des drones flottent dans les airs, des pics bordent certains sols, et les plus grands gouffres ne peuvent être franchis que sur des plateformes mobiles. Atteignez le drapeau à la fin de chaque niveau.
Comment jouer. Marchez avec GAUCHE et DROITE, maintenez B pour courir, appuyez sur A pour sauter. Maintenez A plus longtemps pour sauter plus haut. Atterrissez sur un ennemi pour l’écraser, et sautez dans un bloc ? par en dessous pour en faire sortir un engrenage. Vous avez trois cœurs ; les pics et les ennemis en retirent un, tout comme une chute dans un gouffre.
Comment ça marche. Les niveaux font 128 x 14 tuiles, générés par un petit script et collés dans le sketch sous forme de chaînes. Le robot est une boîte de 10 x 14 pixels, et à chaque image il se déplace en deux étapes : d’abord latéralement, repoussé hors de tout mur dans lequel il se retrouve ; puis verticalement, atterrissant sur le sol, sur une planche à sens unique ou sur une plateforme mobile, ou se cognant la tête contre un bloc. Traiter les deux axes séparément est ce qui empêche le robot de rester collé aux murs ou de glisser à travers les coins.
Trois petites règles rendent le saut agréable. Un saut demandé jusqu’à 0,12 seconde avant l’atterrissage se produit quand même au contact du sol (une mémoire de saut). Un saut demandé jusqu’à 0,08 seconde après avoir quitté un rebord compte quand même (temps coyote). Et relâcher A tôt coupe la vitesse ascendante, ce qui fait que maintenir le bouton donne un saut plus haut. Deux couches de collines défilent à un cinquième et à moins de la moitié de la vitesse de la caméra, ce qui donne de la profondeur à la scène.
Circuit Defense : du tower defense sur une carte de circuit imprimé
Des bugs rampent sur une carte de circuit imprimé vers la puce. Vous construisez des composants électroniques sur la carte pour les arrêter : une LED tire un laser rapide sur un bug, un condensateur se décharge dans tous les bugs autour de lui, et une bobine ralentit les bugs. Chaque bug qui atteint la puce lui coûte un point de vie, et les vagues ne cessent de gagner en puissance.
Comment jouer. Déplacez le curseur avec la croix directionnelle. B choisit le composant, A le construit, et A sur un composant déjà construit l’améliore, jusqu’au niveau 3. Les bugs détruits rapportent des pièces, et chaque vague terminée rapporte un bonus. Le cercle autour du curseur montre la portée du composant que vous êtes sur le point de construire.
Comment ça marche. Les bugs ne suivent pas un tracé fixe. Ils marchent sur la carte libre, et vous pouvez les orienter avec ce que vous construisez : la piste de cuivre sur la carte est toujours l’itinéraire qu’ils emprunteront. Derrière cela se trouve une recherche en largeur, relancée après chaque construction :

La recherche part des cellules voisines de la puce, leur attribue 0, et se propage vers l’extérieur : chaque voisin libre d’une cellule numérotée reçoit ce numéro plus un. Une fois terminée, chaque cellule contient sa distance à la puce, murs de tours compris. Un bug situé sur une cellule se déplace simplement vers n’importe quel voisin portant un numéro plus petit. Il n’y a pas de planification d’itinéraire par bug : une seule recherche, 260 cellules, sert pour tous.
Les mêmes nombres rendent facile l’application de la seule règle du jeu : vous pouvez allonger le chemin, mais jamais le fermer. Lorsque vous construisez, le sketch pose le composant, relance la recherche et examine la cellule d’entrée. Si elle n’a plus de numéro, les bugs ne pourraient pas passer : le composant est retiré et le jeu affiche THAT BLOCKS THE PATH.
ESP32 Doom : un jeu de tir à la première personne
Le plus ancien des cinq tourne sur le classique ESP32 DevKit. Vous parcourez un labyrinthe de murs texturés, tirez sur des robots qui vous poursuivent et sur des slimes qui crachent de l’acide, ouvrez des portes, ramassez des kits médicaux et des munitions, et nettoyez vague après vague.
Comment jouer. La croix directionnelle avance et tourne, A tire (maintenez pour le tir automatique), B ouvre la porte devant vous, et B maintenu avec GAUCHE ou DROITE fait des pas de côté. Les broches diffèrent de celles des jeux XIAO : HAUT sur GPIO 32, BAS 33, GAUCHE 25, DROITE 15, A sur 22, B sur 21, et l’écran sur le bus VSPI de l’ESP32 (SCK 18, MOSI 23, MISO 19, CS 5, D/C 2, RST 4).
Comment ça marche. Doom est un raycaster, la technique de Wolfenstein 3D (1992) : pour chaque colonne de l’écran, il envoie un rayon depuis le joueur dans une carte en grille de 20 x 20 et l’arrête au premier mur. La distance détermine la hauteur à laquelle la tranche de mur est dessinée. Comme l’ESP32 classique n’a pas la place pour une image complète, le sketch construit une colonne à la fois dans un tampon de 200 pixels, avec le sol, le plafond, le mur, les ennemis, l’arme et les effets déjà composés, et l’envoie en une seule rafale :
Les robots marchent droit sur vous et griffent pour 5 points de vie par seconde ; les slimes gardent leurs distances et crachent de l’acide qui coûte 7 points. Un tir touche l’ennemi le plus proche sous le réticule, tant qu’aucun mur n’est plus proche. Chaque ennemi éliminé amène la vague suivante avec deux ennemis de plus, un peu plus rapides et un peu plus coriaces.
Skythread : vol en 3D au-dessus d’un monde généré
Doom est de la 3D en intérieur. Skythread est de la 3D en extérieur : vous pilotez un planeur à aile delta bas au-dessus d’une campagne ouverte, le long de vallées fluviales, au-delà de montagnes et au-dessus de lacs, avec du brouillard vers l’horizon et un ciel qui passe du jour à l’heure dorée puis à la nuit. Des anneaux flottent dans l’air devant vous, et le chronomètre tourne. Vous commencez avec 45 secondes, et chaque anneau en ajoute quelques-unes. Chaque anneau passé d’affilée augmente le combo, jusqu’à cinq fois les points, et traverser le centre d’un anneau rapporte un PERFECT. Manquez un anneau et le combo repart de zéro ; touchez le sol et vous rebondissez dessus, plus lent et trois secondes plus pauvre. Comme les autres, il commence par une démo qui se pilote toute seule.
La console portable. Skythread a été écrit pour la console portable qui fait tourner nos portages de Metal Gear Solid et Castlevania, et non pour la disposition en croix directionnelle des quatre autres : un Seeed Studio XIAO ESP32-S3 Sense, le même écran ILI9341, un joystick analogique à deux axes, deux boutons sur leurs propres broches et six autres sur une seule broche. Dans Velxio, l’exemple s’ouvre disposé comme cette console portable : le joystick à gauche, l’écran au milieu, les boutons à droite et sous l’écran.
| Broche XIAO | Reliée à | Broche XIAO | Reliée à | |
|---|---|---|---|---|
| D8 | écran SCK | D0 | joystick X (gauche et droite) | |
| D10 | écran MOSI | D1 | joystick Y (haut et bas) | |
| D9 | écran MISO | D2 | six boutons, via une échelle de résistances | |
| D3 | écran CS | D5 | FIRE | |
| D6 | écran D/C | D7 | BRAKE | |
| D4 | écran RST | 3V3, GND | alimentation de l’écran, du joystick et de l’échelle |
Comment jouer. Dirigez avec le joystick : cliquez dessus sur le canvas et utilisez les flèches du clavier, ou maintenez la souris sur l’une de ses flèches. Tirez vers l’arrière (bas) pour monter, poussez vers l’avant pour piquer, et à gauche ou à droite pour vous incliner et tourner. FIRE (Z) est une accélération qui vide la barre bleue, et lance aussi une partie. BRAKE (X) vous ralentit pour les virages serrés. START (Entrée) lance et met en pause, CROSS (C) lance aussi une partie, SELECT (Q) revient à la démo, CIRCLE (T) change le moment de la journée, TRIANGLE (W) génère un nouveau monde, et L1 (F) affiche la fréquence d’images.
Six boutons sur une seule broche. Le XIAO a 11 broches, et l’écran, le joystick et huit boutons en demanderaient 16. L’astuce pour six des boutons est une échelle de résistances. Une résistance de 10 kΩ tire D2 vers 3,3 V, et chaque bouton relie D2 à la masse à travers une résistance différente, de sorte que chacun forme un diviseur de tension différent. La broche lit 3,3 V × R / (R + 10 kΩ) :
| Bouton | Vers la masse via | Attendu | Mesuré dans Velxio |
|---|---|---|---|
| CIRCLE | 0 Ω | 0 V | 0 mV |
| CROSS | 2,2 kΩ | 0,595 V | 612 mV |
| TRIANGLE | 4,7 kΩ | 1,055 V | 1065 mV |
| L1 | 10 kΩ | 1,650 V | 1651 mV |
| START | 22 kΩ | 2,269 V | 2258 mV |
| SELECT | 47 kΩ | 2,721 V | 2665 mV |
Le sketch lit D2 avec analogReadMilliVolts() et choisit le bouton dont la tension est la plus proche, avec des seuils à mi-chemin entre voisins (300, 824, 1350, 1960, 2496 et 2960 mV). Velxio résout l’échelle comme un vrai circuit : la dernière colonne correspond à ce que le sketch a imprimé sur le moniteur série lorsque nous avons appuyé sur chaque bouton du canvas. Une échelle ne lit qu’un bouton à la fois, car deux boutons pressés ensemble ressemblent à un seul bouton avec une résistance plus petite. C’est pourquoi le jeu garde FIRE et BRAKE, les deux que l’on maintient en vol, sur leurs propres broches. Il ignore aussi l’échelle tant qu’il ne l’a pas vue relâchée une fois, afin qu’un D2 laissé non connecté ne puisse jamais presser des boutons fantômes.
Comment ça marche. Le monde est généré au démarrage de la carte : une carte 512 x 512 du paysage réalisée avec un bruit diamond-square, où chaque cellule occupe deux octets, un pour la hauteur et un pour une couleur de la palette. Avec une copie à demi-résolution pour le lointain et deux tampons d’image, cela fait environ 940 Ko, ce qui explique pourquoi Skythread a besoin du Sense et de sa PSRAM. Dans Velxio, la construction du monde prend 3 secondes de temps simulé, et la première image atteint l’écran 3,4 secondes après la mise sous tension.
Le dessin utilise le lancer de rayons par colonne des jeux de vol voxel du début des années 1990. Pour chaque colonne de l’écran, le sketch parcourt un rayon depuis la caméra sur la carte, du proche au lointain, jusqu’à 160 pas et 340 cellules de distance ; au-delà de 110 cellules, il lit la carte à demi-résolution à la place. À chaque pas, il convertit la hauteur du terrain à cet endroit en une ligne à l’écran. Si cette ligne est plus haute que tout ce qui a été dessiné jusqu’ici dans la colonne, il remplit l’écart avec la couleur de cette cellule et mémorise le nouveau sommet :

Ce sommet mémorisé par colonne s’appelle un y-buffer. Le sol proche est toujours dessiné en premier, donc le sol lointain ne peut apparaître qu’au-dessus, et aucun pixel n’est jamais peint deux fois. Le brouillard est constitué de 20 palettes, chacune mélangée un peu plus vers la couleur du ciel, une par bande de distance. L’inclinaison est un cisaillement : l’horizon de chaque colonne monte ou descend proportionnellement à sa distance au centre de l’écran, ce qui donne l’impression d’un roulis. Les anneaux, l’ombre du planeur et le soleil sont vérifiés contre le même y-buffer à leur propre distance, de sorte qu’une montagne devant un anneau le cache.
L’image est stockée colonne par colonne, déjà dans l’ordre d’octets attendu par l’ILI9341. Dans l’adressage portrait natif du panneau, une colonne de l’image du paysage est l’une de ses lignes, donc toute l’image part en une seule rafale. Avec deux tampons d’image, les deux cœurs de la puce travaillent en même temps : une tâche sur le cœur 0 envoie une image à l’écran par SPI à 40 MHz pendant que le cœur 1 dessine la suivante.
Le sketch surveille aussi sa propre vitesse. Quand le dessin d’une image prend plus de 22 ms en moyenne, il lance 160 rayons au lieu de 320 et dessine chaque colonne sur deux pixels de large, et il revient à la pleine largeur en dessous de 7 ms. Au-delà de 45 ms, un cas que ses commentaires réservent à un hôte lent comme un simulateur de navigateur, il cesse de faire chevaucher les deux cœurs et attend que chaque image ait fini de partir avant de dessiner la suivante, afin que le panneau simulé reçoive toujours des images complètes. Dans Velxio, il a fonctionné dans ce mode tout du long, à 160 colonnes, dessinant chaque image en 33 à 50 ms de temps simulé.
Fréquences d’images
Nous avons mesuré chaque jeu sur velxio.dev dans un navigateur Chrome sans interface graphique sur notre serveur, en jouant environ une minute chacun.
| Jeu | Rapporté par le sketch (médiane, plage) | Images par seconde en temps réel |
|---|---|---|
| ESP32 Doom | 17,6 (13 à 24) | 16,1 |
| Sky Duel | 28,9 (23 à 38) | 27,2 |
| XIAO Quest | 32,2 (21 à 39) | 30,8 |
| Gear Hop | 27,0 (21 à 35) | 23,4 |
| Circuit Defense | 31,3 (23 à 40) | 29,4 |
| Skythread | 20,4 (16 à 23) | 17,7 |
Deux chiffres par jeu. Le premier est ce que le jeu lui-même rapporte sur le moniteur série, à partir du millis() de la puce : la fréquence d’images de la carte simulée. Le second est le nombre d’images que le navigateur a réellement affichées par seconde de temps réel. Ils diffèrent lorsque l’ordinateur qui exécute la simulation ne peut pas maintenir la puce simulée à pleine vitesse ; le temps simulé s’écoule alors un peu plus lentement que l’horloge murale. Vos propres chiffres dépendent de votre ordinateur.
Les quatre jeux 2D du XIAO tournent à près du double de la fréquence d’images de Doom. Une partie de cela vient du travail : un raycaster lance 320 rayons et calcule le sol et le plafond pixel par pixel. Une autre partie vient du transfert : une seule rafale par image au lieu de 320 petites, chacune avec sa propre fenêtre d’adressage. Skythread, le seul à dessiner un paysage en 3D, tient environ 20 images par seconde en lançant 160 rayons au lieu de 320, le compromis que son propre code fait chaque fois que le dessin d’une image prend plus de 22 ms.
Faites-les vôtres
Chaque jeu est un seul sketch, et le code est organisé en blocs : le moteur, les graphismes, l’état du jeu, la mise à jour et le dessin. Quelques modifications qui prennent une minute :
- Sky Duel : changez la vitesse de croisière (125) ou la vitesse de décrochage (50) dans
fly()et ressentez comment l’avion change. - XIAO Quest : les cartes sont les chaînes dans
MAP_V,MAP_FetMAP_C; les chiffres des monstres sont dans la tableFOES. - Gear Hop : la force de saut est
-335dansmovePlayer(), la gravité est950; essayez la lune. - Circuit Defense : ajoutez une quatrième pièce à
TW_NAME,TW_COSTetupdateTowers(). - Doom :
MAP_SRCest composé de 20 chaînes de 20 chiffres ; chaque chiffre est une texture de mur, et un 9 est une porte. - Skythread :
WORLD_SEEDen haut du sketch choisit le monde dans lequel vous démarrez, etPITCH_PULL_TO_CLIMBréglé sur 0 fait monter le manche lorsque vous le poussez vers l’avant.
Appuyez sur Run après une modification et Velxio compile le sketch modifié, vous pouvez donc changer un nombre et voir le résultat quelques secondes plus tard. Quand cela fonctionne comme vous le souhaitez, le même sketch s’exécute sur un vrai XIAO ESP32-S3 avec un ILI9341 et six boutons câblés comme ci-dessus, et Skythread sur un XIAO ESP32-S3 Sense avec le manche et les boutons de sa section.