Un jeu de labyrinthe rétro. Utilisez les flèches du clavier (↑ ↓ ← →) pour vous déplacer dans le labyrinthe. Mangez les pastilles, évitez les fantômes, et croquez une pastille-énergie pour retourner la situation contre eux.
Appuyez sur une flèche du clavier pour commencer.
Les quatre flèches du clavier dirigent le glouton, et la première pression lance la partie. Une pastille ordinaire vaut dix points, une pastille-énergie en vaut cinquante.
Croquer une pastille-énergie rend les fantômes vulnérables pendant sept secondes. Le premier fantôme avalé rapporte 200 points, le deuxième 400, le troisième 800, jusqu'à un plafond de seize fois la mise de départ. Un fruit apparaît par intermittence au-dessus de la maison centrale et vaut cent points fois le niveau.
La rangée du milieu traverse les murs de gauche à droite: c'est le raccourci quand deux poursuivants convergent. Ramassez toutes les pastilles pour passer au niveau suivant, où les fantômes gagnent un peu de vitesse. Trois vies, aucune continuation.
Le labyrinthe n'est pas dessiné à la main. Je l'ai généré par arbre couvrant en parcours en profondeur, puis mis en miroir gauche-droite, et je l'ai figé dans le code une fois la connexité vérifiée. Il tient dans MAZE_ROWS, vingt-trois colonnes sur dix-neuf rangées de caractères: # pour un mur, . pour une pastille, o pour une pastille-énergie, D pour la porte. La fonction walkable prend un drapeau forGhost, ce qui suffit à réserver la porte et la maison centrale aux fantômes.
Le déplacement est aligné sur la grille. stepEntity avance une entité sur un seul axe vers le centre de la case voisine et ne redemande une direction qu'à l'arrivée exacte sur ce centre. La flèche pressée attend dans keyDesiredDir jusque-là, ce qui donne des virages nets. Les vitesses sont en cases par seconde, 5,4 pour le glouton et 4,6 pour les fantômes, et se multiplient par un delta-time borné à un trentième de seconde, sinon un onglet ralenti ferait traverser un mur.
Chaque fantôme tient une machine à états à quatre positions: inHouse, chase, frightened et eaten. En poursuite, ghostTarget donne à chacun un objectif distinct — poursuite directe, embuscade quatre cases devant, coin tiré au hasard toutes les quatre secondes, ou décrochage dès que l'écart passe sous huit cases. Le choix de direction compare la distance au carré des cases voisines et exclut le demi-tour par isOpposite.
Le retour d'un fantôme mangé est le seul endroit où cette heuristique lâche. Une distance à vol d'oiseau crée des minimums locaux contre les murs et le fantôme s'y coince. J'ai donc précalculé un champ de distances par parcours en largeur, computeDistanceField, conservé dans HOME_DIST. Le fantôme descend le gradient, et le demi-tour y est permis, parce qu'un vrai plus court chemin oblige parfois à rebrousser chemin.
Deux réflexes de mon métier, l'intégration vidéo sur décodeurs et plateformes IPTV, ont servi ici. Le premier: une boucle de rendu ne doit jamais supposer sa cadence. Tant que la position dépend du temps écoulé et non du nombre d'images, la partie se comporte pareil sur un portable poussif et sur un écran à 120 Hz.
Le second: quand un comportement devient difficile à décrire en une phrase, c'est une machine à états qui manque. Les quatre états des fantômes tiennent en un mot chacun, et leur comportement reste lisible des mois plus tard.