ENIB 2024 : Poursuite Brestoise
Titre de la fiche expérience :
Sommaire
Description
Au cours de l'inter semestre de notre troisième année d'étude à l'ENIB, nous avons été amené à réaliser un hackathon avec l'association des petits débrouillards de Brest. Cet hackathon a été réalisé le 24 et le 25 Janvier 2024 et devaient se terminer par une présentation de nos réalisations aux élèves d'une école primaire.
Notre projet consiste en une course poursuite à l'intérieur de Brest au travers de différents monuments de la ville comme les escaliers de la place de Strasbourg ou le téléphérique des Capucins.
Création de la première maquette du projet
Introduction
éventuelle vidéo
Outil et matériel
Pour réaliser ce projet, nous nous sommes servis du matériel mis à notre disposition par l'association. Le matériel initial dont nous disposions pour le faire étais constitué d'une carte programmable, , d'une guirlande de 50 LEDs, d'un switch On/OFF et de 2 boutons mono-état.
En plus de ce matériel, nous nous sommes servit d'une plaque de câblage, de différents fils électrique pour câbler nos différents composants les un avec les autres et de cartons afin de faire notre maquette
Fichiers à joindre
code, ficher d'impression 3D, de découpe laser ou vinyle, ...
Mettre du code Arduino
1
2
3 #include <Adafruit_NeoPixel.h>
4
5 #define NLED 50
6 int PIN3=0;
7
8 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NLED, PIN3, NEO_GRB + NEO_KHZ800);
9
10 const int BOUTON_avancement = 12;
11 const int BOUTON_attaque = 13;
12 int e = 3;
13 int direction = 1;
14 int lvl_1 = 1;
15 int enemy = 20;
16 int lives = 3;
17 int compteur=0;
18 int mort = 0;// Nombre de vies du joueur
19 int compteur1=0;
20 int compteur_tir_enemy=0;
21 int compteur_rebours=0;
22 int compteur_rebours1=30;
23
24
25 void setup() {
26 Serial.begin(9600);
27 pixels.begin();
28 pixels.show();
29
30 pinMode(BOUTON_avancement, INPUT_PULLUP);
31 pinMode(BOUTON_attaque, INPUT_PULLUP);
32 uint32_t enemy_led = pixels.Color(0, 40,40);
33 uint32_t vie = pixels.Color(0, 40,0);
34 pixels.setPixelColor(enemy, enemy_led);
35 pixels.setPixelColor(0,vie);
36 pixels.setPixelColor(1,vie);
37 pixels.setPixelColor(2, vie);
38 randomSeed(analogRead(0));
39 }
40
41 void loop() {
42 uint32_t player = pixels.Color(40, 0, 0);
43 uint32_t tir = pixels.Color(0, 0,40);
44 uint32_t enemy_led = pixels.Color(0, 40, 40);
45 uint32_t game_over= pixels.Color(0,40,0);
46
47
48
49
50
51 Serial.println("démarrage");
52 while (digitalRead(BOUTON_avancement) == HIGH) {
53 if (compteur==0){
54 compteur=0;
55 Serial.println("compteur à 3");
56 if (digitalRead(BOUTON_attaque) == LOW) {
57 Serial.println("AAAAA");
58 pixels.setPixelColor(e + 1, tir);
59 pixels.setPixelColor(e + 2, tir);
60
61 // Vérifier si l'ennemi est à portée
62 if (e + 1 == enemy || e + 2 == enemy) {
63 pixels.setPixelColor(enemy, 0);
64 mort = 1;
65
66 while (mort==1){for (int i=0;i<=10;i++){pixels.setPixelColor(i,game_over);}}
67 }
68 }
69 }
70
71 pixels.setPixelColor(e, player);
72 pixels.setPixelColor(enemy,enemy_led);
73 pixels.show();
74 delay(100-compteur_rebours);
75 pixels.setPixelColor(e, 0);
76 pixels.setPixelColor(enemy, 0);
77 if(compteur_rebours1==0){
78 compteur_rebours1==30;
79
80 compteur_rebours=compteur_rebours+5;}
81 compteur_rebours1--;
82
83 // Gestion de la collision avec l'ennemi
84 if (e == enemy) {
85
86 if (mort == 0) {
87 lives--;
88 pixels.setPixelColor(lives,0);
89 pixels.setPixelColor(enemy, enemy_led);
90 }
91
92 // Si le joueur n'a plus de vies, réinitialiser le niveau
93 if (lives<= 0) {
94 lives = 3; // Réinitialiser le nombre de vies
95
96 // Réinitialiser la position du joueur et de l'ennemi
97 e = 5;
98 pixels.setPixelColor(enemy,0);
99 enemy = 20;
100 while(mort==0){pixels.setPixelColor(0,game_over);}
101
102 pixels.setPixelColor(enemy, enemy_led);
103 pixels.setPixelColor(enemy,0);
104 pixels.setPixelColor(enemy+1, 0);
105 pixels.setPixelColor(enemy+2,0);
106 }
107 }
108
109 // Générer une direction aléatoire pour l'ennemi
110
111 e = e +1;
112 if (compteur1==0){
113 compteur1=5;
114 int valuerandom2=random(2);
115 int value2=(valuerandom2==0) ? -1:1;
116 enemy=enemy+value2;
117 int valuerandom1=random(3);
118 if(valuerandom1==0){int B=random(2); pixels.setPixelColor(enemy+B, tir);
119 delay(10);
120 pixels.setPixelColor(enemy+B,0);}}
121
122 if (e == NLED || enemy==NLED) {
123 while (digitalRead(BOUTON_avancement) == HIGH) {}
124 }
125 //compteur--;
126 compteur1--;
127 }
128 pixels.setPixelColor(e+1, 0);
129 pixels.setPixelColor(e+2,0);
130
131
132
133 while (digitalRead(BOUTON_avancement) == LOW) {
134 if (compteur==0){
135 compteur=0;
136 if (digitalRead(BOUTON_attaque) == LOW) {
137 pixels.setPixelColor(e - 1, tir);
138 pixels.setPixelColor(e - 2, tir);
139 Serial.println("j'appuie");
140 // Vérifier si l'ennemi est à portée
141 if (e - 1 == enemy || e - 2 == enemy) {
142 pixels.setPixelColor(enemy, 0);
143 mort = 1;
144
145 while (mort==1){for (int i=0;i<=10;i++){pixels.setPixelColor(i,game_over);}}
146 }
147 }
148 }
149
150 pixels.setPixelColor(e, player);
151 pixels.setPixelColor(enemy,enemy_led);
152 pixels.show();
153 delay(100-compteur_rebours);
154 pixels.setPixelColor(e, 0);
155 pixels.setPixelColor(enemy, 0);
156 if(compteur_rebours1==0){
157 compteur_rebours1==30;
158
159 compteur_rebours=compteur_rebours+5;}
160 compteur_rebours1--;
161 // Gestion de la collision avec l'ennemi
162 if (e == enemy) {
163
164 if (mort == 0) {
165 lives--;
166 pixels.setPixelColor(lives,0);
167 pixels.setPixelColor(enemy, enemy_led);
168 }
169 if (mort == 1) {
170
171
172 }
173
174
175 // Si le joueur n'a plus de vies, réinitialiser le niveau
176 if (lives <= 0) {
177 lives = 3; // Réinitialiser le nombre de vies
178
179 // Réinitialiser la position du joueur et de l'ennemi
180 e = 3;
181 pixels.setPixelColor(enemy,0);
182 enemy = 20;
183 ;
184 while(mort==0){pixels.setPixelColor(0,game_over);}
185 pixels.setPixelColor(enemy, enemy_led);
186 pixels.setPixelColor(enemy,0);
187 pixels.setPixelColor(enemy-1, 0);
188 pixels.setPixelColor(enemy-2,0);
189
190 }
191 }
192
193 // Générer une direction aléatoire pour l'ennemi
194
195 e = e - 1;
196 if (compteur1==0){
197 compteur1=5;
198
199 int valuerandom=random(2);
200 int value=(valuerandom==0) ? -1:1;
201 enemy=enemy+value;
202 int valuerandom1=random(3);
203 if(valuerandom1==0){
204 int tir_enemy=random(2);
205 pixels.setPixelColor(enemy+tir_enemy, tir);
206 pixels.setPixelColor(enemy+tir_enemy, tir);
207 }
208
209 }
210
211
212
213
214 if (e == 5 || enemy==5) {
215 while (digitalRead(BOUTON_avancement) == LOW) {}
216 }
217 //compteur--;
218 compteur1--;
219 }
220
221 pixels.setPixelColor(e-1, 0);
222 pixels.setPixelColor(e-2,0);
223
224 }
Etapes de fabrication
étape 1
La première étape du projet a été de trouver une idée de jeu à réaliser avec le matériel à notre disposition. Après plusieurs idée abandonnée rapidement, nous nous sommes mis d'accord pour faire un jeu de poursuite et de tir avec notre bande de LED.
étape 2
Dans un second temps, Axel et Mathieu ont commencé à s'occuper de la maquette du projet tandis que Malo et Alexandre cherchaient une façon de réaliser le code du projet. La maquette a été réalisé durant la première matinée et la première variante du code pu être testée au début de la première après-midi.
étape 3
Au début du premier après-midi, nous avons subit plusieurs contre temps notamment concernant le branchement entre l'ordinateur et la carte. La solution a ce problème fut trouvé vers 15h, il manquait une extension sur l'ordinateur pour faire fonctionner notre carte programmable. Cependant, ce soucis n'étais pas la dernier, en effet la fin de cette première journée n'a pas été concluante, le code ne fonctionnant pas et aucune solution n'étant trouvée.
étape 4
Le début de la seconde journée fut bien plus productive avec des améliorations du code arrivant dans les premières heures, rendant le projet fonctionnel. Pendant ce temps, l'équipe de décoration s'occupe de créer de nouveaux éléments de décor pour rendre notre projet plus vivant. Afin de faire comprendre l'origine du nom de notre projet : "Poursuite Brestoise", nous avons décidé de créer des éléments rappelant la ville comme notamment l'escalier de la place de Strasbourg, le téléphérique ...
étape 5
Pour la fin de la matinée, tous les décors étaient finis et le code était fonctionnel. Nous avons monté nos construction au début de l'après-midi et afin d'être prés pour la présentation de notre travail. L'une des partie les plus dure fut le rangement des câbles au sein de la maquette. En effet, pour obtenir un rendu propre, aucun éléments technique ne devaient être apparent.
troubleshouting
Au cours du projet nous avons rencontrés de nombreux problèmes notamment au niveau du code. En effet, en créant nous même le code, nous nous sommes mis une contrainte supplémentaire (il aurais été plus simple de partir d'un code déjà existant mais nous avons créé le notre depuis le départ). Les problèmes de code ont été nos principaux soucis.