1. Introduction

Le Snake est un jeu vidéo iconique dans lequel le joueur contrôle un serpent. Le but du jeu est de survivre tout en marquant le plus de score possible, cela en mangeant des fruits. Le serpent s’agrandit au fur et à mesure et le jeu se termine un fois que celui-ci rentre dans une des bordures du jeu ou rencontre son propre corps.

Après avoir découvert un bloc de LEDs qui fut soudé par un élève de l’an passé, j’ai eu l’idée de créer pour mon projet d’hiver un Snake mais en 3D. Le jeu sera donc affiché sur le bloc de LEDs. Cependant, puisque le bloc de LEDs contient uniquement des LEDs vertes, je ne peux pas afficher de fruit. Le but du jeu sera alors de survivre le plus longtemps possible sachant que le serpent s'allongera d'une LED toutes les cinq secondes. Le joueur pourra controller le serpent à l'aide de six boutons, quatre pour chaque direction et deux pour changer d'étage.

2. Matériel et méthodes

2.1 Matériel

  • Bloc de 54 LEDs vertes
  • Raspberry Pi 3B
  • Breadboard de taille large
  • Une trentaine de câbles
  • Trois résistances de 330Ω
  • 6 Boutons

2.2 Méthode

Hardware

Tout d'abord il faut placer le bloc de LEDs sur la breadboard. L'élève ayant soudé ce bloc l'année précédente a mis à disposition sur le blog des projets des images indiquant comment il faut monter le tout. Lors de cette étape, il faut s'assurer que chaque fil de fer du bloc de LEDs rentre correctement dans la breadboard puisque chacun possède une longueur différente. Certains étant plus petits que d'autres, il faut donc bien enfoncé le bloc. Concernant le branchement, il faut réussir à mettre tous les câbles sans enlever les LEDs. Ensuite, je me suis malheureusement rendu compte que je ne pourrai pas jouer au jeu avec des boutons directement mis sur la breadboard puisque tous les pins sont en fait déjà occupés par le bloc de LEDs. J'ai donc décidé de pouvoir controller le serpent à l'aide des flèches directionnelles d'un clavier ainsi que des touches 'page up' et 'page down'.

Figure 1 - Bloc de 54 LEDs monté sur la breadboard IMG_7609.JPG, fév. 2022

Software

Pour le code de mon projet, je commence tout d'abord par importer les différentes librairies dont j'ai besoin.

import RPi.GPIO as GPIO
import pygame as p
import os

Bien sûr il me faut la librairie RPi.GPIO afin d'allumer les LEDs en commandant chaque pin. Ensuite j'ai décidé d'utiliser la librairie pygame, malgré que celle-ci ait besoin d'une interface graphique, afin de pouvoir enregister les inputs provenant d'un clavier et que je ne connais pour le moment pas d'autre librairie permettant cela. La troisième librairie que j'ai importé permet de résoudre un problème qu'engendre pygame à cause du fait qu'il n'y ait pas d'écran directement branché au Raspberry et que je suis connecté à ce dernier en SSH.

pygame.error: video system not initialized

ou

pygame.error: unable to open a console terminal

Il me faut alors utiliser cette commande que j'ai trouver sur un forum afin de modifier l'output d'affichage.

os.environ["DISPLAY"] = ":0"

Maintenant je souhaite que le joueur commence à partir de la LED qui se situe tout en bas à gauche. Pour cela je crée deux variables indiquant les deux pins nécessaires pour allumer la LED de départ. Par la suite, ces variables seront toujours actualisées lorsque le joueur appuie sur une touche.

Position = 17
Floor = 8

try:
        GPIO.setup(Position, GPIO.OUT)
        GPIO.setup(Floor, GPIO.OUT)


        while True:
                GPIO.output(Position, GPIO.HIGH)
                GPIO.output(Floor, GPIO.LOW)

Je décide de ne pas 'setup' tout les pins en tant qu'output en même temps puisque lorsque je fais cela il y a bizarrement toutes les LEDs se trouvant dans les coins qui s'allument sans même qu'il ait un output en 'GPIO.HIGH'.

Afin d'enregistrer les inputs du joueur, voilà qu'intervient pygame.

while True:
        for e in p.event.get():
                if e.type == p.KEYDOWN:

Ces trois lignes que j'ai recherché dans la documentation de la librairie s'occupent d'enregistrer n'importe quel input provenant d'un clavier.

Il faut maintenant que le joueur puisse se déplacer horizontalement.

                        if e.key == p.K_RIGHT:
                                Position = Position - 1
                                if Position == 15:
                                        Position = 13
                                elif Position == 11:
                                        Position = 6
                                elif Position == 5:
                                        Position = 7
                        elif e.key == p.K_LEFT:
                                Position = Position + 1
                                if Position == 8:
                                        Position = 6
                                elif Position == 7:
                                        Position = 12
                                elif Position == 14:
                                        Position = 16

Ces lignes ci-dessus permettent au joueur de ce déplacer lorsqu'il appuie sur ses touches. La position de la prochaine LED à allumer est actualisée par rapport à la position précédente mais puisque la numérotation des pins ne suit pas un ordre précis, il faut indiquer que l'on passe à un certain pin selon les cas.

Ensuite, il faut faire en sorte que le joueur puisse changer d'étage.

                        elif e.key == p.K_PAGEUP:
                                Floor = Floor + 1
                                if Floor == 11:
                                        Floor = 10
                        elif e.key == p.K_PAGEDOWN:
                                Floor = Floor - 1
                                if Floor == 7:
                                        Floor = 8

Lorsque le joueur appuie sur 'page up', il monte d'un étage. Si le joueur se trouve déjà au dernier étage du bloc de LEDs et qu'il décide d'appuyer une seconde fois sur sa touche pour monter, il restera au même étage. Et lorsque le joueur appuie sur 'page down', pour déscendre d'un étage donc, mais qu'il se trouve déjà au premier étage , il restera au même étage.

Pour la programmation de l'élongation du serpent, je n'ai cependant pas d'idée sur comment faire cela. Le code du jeu s'arrête donc ici avec une seule LED que le joueur devrait pouvoir déplacer à l'aide de son clavier.

3. Résultats

Le rendu final ne correspond pas à l'idée d'origine puisque je ne peux pas ajouter des boutons à la breadboard. Malheureusement lors de l'éxecution du code, je n'obtiens pas le résultat attendu car toutes les LEDs du bloc restent éteintes et il n'y a aucun retour.

4. Discussion

Je ne pense pas qu'il y a un moyen d'avoir plus de pins à disposition afin d'ajouter des boutons à la breadboard puisque je trouve déjà la manière dont le bloc de LEDs fut soudé très intelligente.Celui-ci ne prend que 21 pins alors que il y a 54 LEDs. Je ne crois pas que le fait qu'il n'y ait aucune LED qui s'allume provienne d'un problème du côté hardware. En effet, j'ai testé si chaque LED arrivait à s'allumer correctement et toutes fonctionnaient belle et bien. J'éstime alors que mon code doit contenir une ou plusieurs erreurs (pas dans le sens informatique). D'ailleurs, le fait que j'utilise énormément de 'if' et de 'elif' à la suite me fait dire qu'il ne s'agit sûrement pas de la bonne manière de faire. Je pense aussi que je n'aurais pas dû utiliser la librairie pygame pour un projet comme celui-ci puisqu'il s'agit d'une librairie qui utilise des interfaces graphiques, ce dont nous n'avons pas besoin ici. Il aurait fallut utiliser une autre librairie qui s'occupe des inputs provenant d'un clavier.

5. Conclusion

L'objectif de ce projet n'a pas été atteint. Je conclus que j'ai sous-estimé la difficulté de la programmation du jeu puisque je n'ai pas obtenu le résultat attendu et que je ne sais pas comment faire en sorte que le serpent en entier se déplace, c'est-à-dire que les LEDs allumées se suivent puis s'éteignent au fur et à mesure. J'ai aussi sous-estimer le temps que ce projet devait prendre.

J'ai tout de même appris à me documenter un peu sur certaines librairies tel que pygame et comment résoudre certaines erreurs. Je retiens surtout que je devrai me prendre plus à l'avance pour la prochaine fois.

Références

  • https://www.pygame.org/docs/
  • https://raspberrypi.stackexchange.com/questions/117484/pygame-error-unable-to-open-a-console-terminal