Redstone Snake complet et rapide ! [un déplacement toutes les 1,2 secondes]

[GISED] Link

Torches, poudre et repeaters. What else ?
4 Mars 2012
341
76
140
29
VNSA, 2740 Moutier
vnsa.ch
730874ThundeRedbannire2.jpg

Heeeeeeeeeeello les gugus. Comme je vois que ça fait un moment que ya plus trop eu de truc balaise en redstone depuis un bout de temps ici, je vais tenter de redonner un petit coup de souffle. Pour ce faire, je vais vous présenter la première partie de notre projet entre moi et Zilack3. Je précise que le projet est en mode de finalisation. C'est à dire qu'il fonctionne, mais qu'il y a encore quelques bug et quelques fonctions par encore testées complètement. Mais vous aurez la map très bientôt mes petits loups.

Snake - Partie déplacement
85447620151112105153.png

- image de la partie redstone de tout le snake

Caractéristiques :
  • Ecran de jeu 8x8 pixels, chaque pixel fait 2 cubes sur 2
  • Ecran auxiliaire pour régler les paramètres, lancer une partie, afficher le score et programmer un niveau
  • 3 modes de jeu :
    • Simple, sans mur
    • Difficile, murs pré-programmés
    • Personnalisé, avec mur programmé sois-même
  • Super rapide avec une période d'actualisation de 1.2 secondes !
  • Longueur du corps limité à 16 cases
  • Déplacement cross-plateau (c'est à dire par ex. passer de tout à droite à tout à gauche) autorisé ou non. A choix
  • Tout en redstone traditionnel, c'est à dire que poudre, torche et repeater ! (avec lampe pour l'affichage)
  • Système de score évolué, avec système de combo
  • Lancer une partie, mettre en pause et redémarrer après un game over en un seul bouton
  • Un magnifique écran de gameover. Juste ça.
La vidéo !
Le jeu

Pour le principe, il est semblable aux autres snakes. Vous êtes donc un serpent qui se déplace sur le plateau. Votre rôle est de manger la nourriture tout en évitant de manger les murs ou se manger sois-même. A chaque fois que vous mangez une nourriture, votre corps grandit d'une case. Vous comprendrez donc que votre corps deviendra vite votre principal obstacle. C'est pourquoi la ligue contre l'obésité soutient ce jeu.​

Le fonctionnement

Alors comment on implémente le jeu dans Minecraft ? Il y a, comme souvent en informatique, plusieurs possibilités. Je vais vous présenter le fonctionnement que nous avons effectivement implémenté.
Alors le fonctionnement initial a été pensé par Zilack3. Nous avons ensuite travaillé ensemble dessus et voici - après plusieurs mois de conception, d'implémentation et de test - le résultat :
567875SchmagnralV2.jpg

Générale

Alors je vais vous détailler, avec des mots, le fonctionnement général du snake. Basez-vous sur le schéma juste au dessus. Il est important de savoir que la position du snake est séparée en 2 parties : la coordonnée en X et celle en Y. Ces coordonnées sont codées en "unaire", c'est à dire qu'il y a un bit dédié à chacune des coordonnées. Comme c'est un écran 8x8, il y a donc 8 positions en X et pareil en Y. On retrouvera donc 8 bits pour la coordonnée en X et 8 pour celle en Y. Il était possible de coder les positions en binaire, c'est à dire d'avoir 3 bits par coordonnée (plus de 2x plus petit !). Mais cela avait/aurait posé de gros problèmes pour la vérification des collisions. En effet, il aurait fallu utiliser des XOR à la place des simples portes ET. Mais nous y reviendrons...
Le snake est composé principalement de :​
    • Un écran, qui se contente de convertir des signaux redstone en pixel lumineux
    • Une ROM d'écran, utilisée pour forcer l'affichage d'une tête de mort une fois la partie terminée
    • Une mémoire d'écran, appelée Module RS, qui permet de set ou de reset des pixels de l'écran
    • Un système de matrice, qui permet de croiser une coordonnée en X et une coordonnée en Y afin de gérer un écran en 2D
    • Un multiplexeur, qui gère les 3 différents éléments dynamiques durant le jeu, soit la tête du serpent, la queue et la nourriture
    • Un module de gestion de la tête, qui permet le déplacement de celle-ci à l'aide de 4 dalles
    • Un générateur aléatoire pour la gestion de la nourriture
    • Un module de gestion de corps, qui permet de stocker les différents points du corps du serpent, de les shifter (=déplacer l'ensemble du contenu d'une case) à chaque fois que le snake se déplace (à chaque coups d'horloge)
    • Un module de gestion de la taille, qui est en fait un simple compteur unaire qui s'incrémente à chaque fois qu'on gnomgnomgnom une nourriture
    • Une RAM, pour stocker la position des murs envoyée avant le premier déplacement du snake
    • D'un module de vérification des collisions, ensemble tout bête de porte ET très simple
    • et une ROM, pour stocker la position des murs déjà créés.
La plupart de ces modules est doublés (voir schéma bloc) car il faut gérer aussi bien la position en X que en Y. Il y a aussi des modules de communication (recevoir les ordres du joueur), des modules de clocks et des circuits de séquençage. Mais ceux-ci permettent juste de synchroniser tous les blocs plus haut, et malgré qu'ils sont très important, ils ne sont pas assez conséquent pour qu'on s'attarde dessus.
A l'écran
608374Gestionecran.png


Il y a, sur l'écran, jusqu'à 3 éléments différents. Le serpent (la partie qui se déplace), la nourriture (la partie qui "pop" une fois qu'on l'a mangé), et les murs. Les trois ont la même couleur à l'écran, simplement car on a un écran bicolore. Pas toujours très pratique, mais on s'en sort quand même. La position de la tête, de la queue et la nourriture sont gérées via le multiplexeur (juste derrière la matrice). Nous devons multiplexer le signal puisqu'il n'est possible d'ajouter ou de supprimer qu'un point à la fois à l'écran. Alors le multiplexeur choisis l'une de ces trois valeurs toutes les 0,4 seconde (le temps de mettre à jour la RS dans le modules RS), dans un ordre défini. Le point ainsi sélectionné va être traiter dans le Modules RS afin d'être sauvegardé ou supprimé (on ajoute une nouvelle position de la tête, puis on supprime la position de la queue, puis on ajoute la position de la nourriture. On recommence cela jusqu'à la MORT). La ROM est juste un étage intermédiaire qui permet simplement d'afficher une tête de mort. Ça fait jolie. Ensuite l'écran qui sert simplement à allumer des redstone lamps.
Pour ce qui est des murs, ceux-ci sont générés au moment où on sélectionne le niveau. C'est à dire qu'on set l'ensemble des points une fois à l'écran. Puis ces points seront fixes et ne seront plus jamais touchés jusqu'au nettoyage de l'écran et le chargement d'une nouvelle partie.
Déplacement
802808gestionducorps.png


Il est bon de savoir que le serpent est composé de trois parties : la tête, le corps et la queue. Notez que la queue est une position particulière du corps (c'est pourquoi c'est la même mémoire qui gère le corps et la queue).

- La tête -
Pour gérer la position de la tête, j'utilise un compteur qui s'incrémente, ne bouge pas ou se décrémente en fonction de la direction du serpent. Cependant, le compteur prends pas mal de temps pour se mettre à jour (~0,8 seconde), ce qui est un peu lent niveau réactivité. J'ai donc ajouté à la sortie du compteur un module de pré-calcule de position. C'est pas très compliqué, c'est juste un module combinatoire qui se contente de décaler la valeur actuel à droite ou à gauche de 1 bit selon le déplacement du joueur, et qui est bien plus réactif que le compteur (0,3 seconde). Cette valeur change à chaque coup d'horloge.

- La nourriture -
Pour la gestion de la nourriture, j'ai créé un circuit qui permet de parcourir toutes les coordonnées de l'écran. Il suffit simplement de générer une nouvelle coordonnée à chaque coup d'horloge. J'utilise pour ce faire un compteur unaire par coordonnée (aaah... les compteurs...). Cependant, il ne faut pas incrémenter la position en X et en Y de la même manière, sinon on a toujours les même 8 points à l'écran! Pour palier à ce problème j'utilise un Registre à décalage à rétroaction linéaire de 4 bits ce qui permet de générer une suite de 0 et de 1 de manière aléatoire. Ainsi, tout dépend si j'ai un 1 ou un 0, j'incrémente plus ou moins vite les compteurs de gestion de la nourriture (comprenez que c'est assez complexe). Mais ça marche.

- Le corps -
Pour la gestion du corps, j'utilise une mémoire FIFO (premier arrivé, premier sorti, First In, First Out). Cette mémoire est en faite un registre à décalage dans lequel je choisis où ma donnée entre à l'aide d'un compteur (je peux donc entrer une valeur en plein milieu de la mémoire et pas forcément tout au début, comme c'est souvent le cas pour les registres à décalage). Et cette valeur que je rentre où je veux, c'est la dernière position de la tête. Ben oui, la position de la tête devient le corps puisqu'on génère à chaque fois une nouvelle position de la tête. Et lorsque le serpent se déplace d'une case, c'est tout le corps qui est décalé. Et la dernière position est toujours celle de la queue. Ce qui veut dire que la coordonnée de la queue change à chaque coup d'horloge. C'est justement ce qu'on veut. Ainsi nous pouvons toujours envoyer le même slot (= emplacement) de mémoire au multiplexeur.
Donc si je résume : la coordonnée de la tête est envoyée à la mémoire, la mémoire se schift d'une case, la position de la queue est mise à jour, et on renvoie la coordonnée de la tête, etc... En fin de compte, c'est pas très compliqué.
Pour augmenter la taille du serpent, il suffit d'incrémenter le compteur (gestion taille) pour que la position de la tête entre une case avant.

- Les murs -
Les murs sont sauvegardés en ROM (soit une mémoire fait de torche de redstone que l'on place une fois et qui ne bougerons plus). Nous pouvons avoir ainsi plusieurs niveau au sein du même jeu. Cependant, il faut charger les murs dans la RAM (mémoire qui, cette fois-ci, est gérer via la redstone) avant de débuter une partie. Il y a donc toute une partie dédié à cela. Je vais pas étendre le sujet, juste noter que le contenu de la RAM n'est pas envoyé automatiquement à l'écran. Il a fallu ajouter un circuit supplémentaire afin d'envoyer les données aussi à l'écran.

- Les structures de vérifications -
Comment savoir si il y a eu des collisions ? En ajoutant des circuits dédiés aux contrôle. Alors, dans le fond, il s'agit simplement de porte ET qui compare la coordonnée de la tête avec soit la position des murs, la position de la nourriture ou la position du corps. En effet, comme il n'y a qu'un bit à 1 à la fois, on peut sans autre dire : Si ce bit de la tête est à 1 et que le bit correspondant du corps est aussi à 1, alors il y a contact. N'oublier par qu'il faut gérer X et Y. Mais à nouveau, il suffit, pour la même case, de regarder s'il y a une collision en X ET en Y. Donc, une simple porte ET.

- Gestion du système -
Alors une fois qu'on a détecté un contact entre la tête et la nourriture, on génère une nouvelle nourriture et on augmente la taille du serpent de un (incrémenter le compteur de la gestion de la taille du serpent). Si la tête touche un mur ou son corps, game over. Si la nourriture est générée sur un mur, il faut donc en générer une nouvelle. La gestion du game over, nouvelle partie etc. ce fait à l'aide d'une RS NOR Latch, d'une T-Flipflop et de quelques portes logiques. Vraiment rien de bien méchant.
Conclusion
Pfiou ! J'ai mal aux doigts moi ^^. Bref, je vous ai présenté ici que la partie "gameplay" du snake. Il y a encore beaucoup de chose à vous montrer ! Comme par exemple des screenshots de l'écran in game, que vous découvrirai dès qu'on sortira la vidéo trailer. J'espère avoir et prendre le temps de faire une vidéo en détaillant chacun des points décris plus-haut, et de pouvoir voir chacun des circuit en fonctionnement. J'espère que le projet vous intéresse, et que vous aurez plein de question sur le sujet, ou des remarques à faire !

Bonne redstone à tous !
 
Dernière édition:
  • J'aime
Reactions: Xuwar et Télumire

Gaël Erhlich

Installateur de radiateurs
21 Décembre 2014
1 544
382
217
Ici-même
Up ! Personne n'a de question ?

On va dire que les intéressés par la redstone physique ne sont plus légions depuis pas mal de versions déjà, alors y'a pas grand monde qui se penche vraiment sur la chose et qui en plus ait des questions.
Ou alors, c'est tellement clair que tu pourrais devenir prof'. c:
 

[GISED] Link

Torches, poudre et repeaters. What else ?
4 Mars 2012
341
76
140
29
VNSA, 2740 Moutier
vnsa.ch
Mes petits loulous, j'ai une petite image à vous passer !

62510220151203025822.png


Vous l'aurez deviné, il s'agit de l'écran principal du snake (que j'ai mis en pause le temps de la photo) ! On y voit un niveau chargé (ici une tête de creeper), le serpent qui fait en ce moment 3 cases (en bas à droite) ainsi que la nourriture qu'il s’apprête à manger. J'espère que le choix du décor vous plaît !

Nous travaillons toujours dessus afin de trouver tous les petits bugs et les corriger. Ainsi, vous aurez une version parfaitement fonctionnelle dès sa sortie !

J'espère que vous attendez aussi impatiemment la sortie de ce snake que nous (ouais... nous on est impatient de pouvoir vous le montrer ^^).
 
Dernière édition:
  • J'aime
Reactions: Daucus carota

Zilack3

Binary Power !
13 Mars 2013
118
54
140
26
On va dire que sur les 12 derniers mois, on a fait chacun 1 semaine de travail, soit 2*7*24 = 336h totale. Bien sûr, ce n'est qu'une grosse estimation, il n'y a rien de très précis là-dedans...
 

spirou201

Aventurier
9 Décembre 2015
30
1
9
C'est un travail de fou, Bravo!!!
J'ai juste une question par rapport à l'afficheur,
il a une taille de 8 * 8 cases, chaque case a une taille de 2 * 2. Et tu réussis à "allumer" chaque case individuellement. Je ne comprends pas comment.
 

Zilack3

Binary Power !
13 Mars 2013
118
54
140
26
Non, en fait l'écran à une taille de 8*8 pixels et chaque pixel est constitué de 2*2 redstone lamp. Finalement on ne peut allumer qu'un pixel parmis les 64(=8*8) et non les 256 (=8*8*2*2) xD