ENIB 2022 : Catch the middle
Sommaire
Photo du projet
Projet réalisé par :
-Yann Le Masson -Hugo Boulouard -Malo Cadier -Léo Orveillon
Que fait ce projet ?
Jeux ludique dans lequel la réactivité prime.
Une lumière se balade le long du ruban, le joueur doit appuyer sur le bouton dès que la lumière arrive au centre.
La lumière accélère au fil du temps
Le projet fonctionne autour d'une carte arduino sur laquelle on branche un bouton et un ruban de leds
Liste des composants
- Bouton poussoir style Arcade
- Arduino nano
- 2 rubans de LED adressable (85 LEDs pour être exacte)
- Carton
- Câbles mini-USB
- Câbles
Outils
- Cutter
- Marqueur noir
- Pistolet à colle
- Scotch
- Fer à souder
- Bibliothèque Arduino FastLed
https://fastled.io/
Réalisation
Branchez tous les rubans de LEDs en série
Ensuite, suivez le schéma ci-dessous :
Code
1 #include "FastLED.h" //bibliothèque pour controler le ruban led
2 #define NUM_LEDS 86
3 #define NUM_OF_LEDS_BY_LEVEL 17 // nombre de leds par niveau
4 #define NUM_OF_LEVELS 5 // nombre de niveaux
5 #define PIN_BTN 3 // Entree du bouton
6 #define PIN_LEDS 2 // Sortie du ruban led
7
8 // Dans ce programme nous avons utilisé presque intégralement des variables globales
9
10 CRGB leds[NUM_LEDS];
11 int level = 0; // niveau auquel le joueur est
12 int delay_level = 30; // délai qui permet de controler la vitesse de déplacement de la led
13 auto color = CRGB::Purple; // couleur de la led qui se déplace
14 int score = 0; // socre du joueur
15 const double coef[] = {1, 1.4, 1.7, 1.9, 2, 2.2}; // coefficient multiplicateur de point par niveau
16 int last_point = 0; // sauvegarde de la derniere led allumée pour la rallumer après flash()
17
18
19 // Déclarations de fonctions
20 int compute_score(int score_of_level); // calcul du score par niveau
21 int up(); // deplacement led
22 int down(); // deplacement led dans l'autre sense
23 void level_up(); // passage de niveau
24 void flash(); // animation de victoire d'un niveau
25
26
27 void setup() {
28 FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS); // setup du ruban de led sur la sortie PIN_LEDS => 2
29 pinMode(PIN_BTN, INPUT); // setup du bouton dur l'entrée PIN_BTN => 3
30 Serial.begin(9600); // setup moniteur série pour debug
31 }
32
33 void loop() {
34
35 int score_of_level;
36 if (score_of_level = up()) // led avance dans un sense
37 {
38 score += compute_score(score_of_level); // ajout score du niveau
39 level_up();
40 }
41 else if (score_of_level = down()) // led avance dans l'autre sense
42 {
43 score += compute_score(score_of_level); // ajout score du niveau
44 level_up();
45 }
46
47
48 }
49
50 int compute_score(int score_of_level)
51 {
52 return (NUM_OF_LEDS_BY_LEVEL/2 - (int)abs((level * NUM_OF_LEDS_BY_LEVEL + NUM_OF_LEDS_BY_LEVEL / 2) - score_of_level)) * coef[level] + 1;
53 // On calcul le nombre de leds d'un niveau moins la différence entre la led du joueur et celle du milieu on ajoute 2 et on multiplie par le coefficient de points du level
54 }
55
56 int up()
57 {
58 for (int i = NUM_OF_LEDS_BY_LEVEL * level; i <= (NUM_OF_LEDS_BY_LEVEL * level + NUM_OF_LEDS_BY_LEVEL - 1); i++)
59 {
60 if (digitalRead(PIN_BTN)) // appuie sur le bouton
61 {
62 while (digitalRead(PIN_BTN)) // blocage du bouton tant que celui-ci n'a pas été relaché
63 {
64 delay(2);
65 }
66 last_point = i-1; // on concerve la valeur de la led choisie pour la réafficher après le flash
67 return i - 1; // renvoie la position de la led au moment de l'appuie sur le bouton
68 }
69 leds[i - 1] = CRGB::Black;
70 delay(3);
71
72 leds[level * NUM_OF_LEDS_BY_LEVEL + NUM_OF_LEDS_BY_LEVEL / 2] = CRGB::White;
73 leds[i] = color;
74
75 FastLED.show();
76 delay(delay_level);
77 }
78 leds[NUM_OF_LEDS_BY_LEVEL * level + 20] = CRGB::Black;
79 FastLED.show();
80 delay(delay_level);
81 return 0;
82
83 }
84
85 int down()
86 {
87
88 for (int i = NUM_OF_LEDS_BY_LEVEL * level + NUM_OF_LEDS_BY_LEVEL - 1; i >= NUM_OF_LEDS_BY_LEVEL * level ; i--)
89 {
90 if (digitalRead(PIN_BTN))
91 {
92 while (digitalRead(PIN_BTN))
93 {
94 delay(2);
95 }
96 last_point = i+1;
97 return i + 1; // renvoie la position de la led au moment de l'appuie sur le bouton
98 }
99 leds[i + 1] = CRGB::Black;
100 delay(3);
101
102 leds[level * NUM_OF_LEDS_BY_LEVEL + NUM_OF_LEDS_BY_LEVEL / 2] = CRGB::White;
103 leds[i] = color;
104
105 FastLED.show();
106 delay(delay_level);
107 }
108 leds[NUM_OF_LEDS_BY_LEVEL] = CRGB::Black;
109 FastLED.show();
110 delay(delay_level);
111 return 0;
112
113
114 }
115 void flash() // fonction de décoration qui fait clignoter les leds en blanc avant le passage de niveau
116 {
117 for (int cpt = 0; cpt < 4; cpt++)
118 {
119 for (int i = NUM_OF_LEDS_BY_LEVEL * level; i <= (NUM_OF_LEDS_BY_LEVEL * level + NUM_OF_LEDS_BY_LEVEL - 1); i++) // On met toute les leds du niveau en blanc
120 {
121 leds[i] = CRGB::White;
122 }
123 FastLED.show();
124
125 delay(100);
126 for (int i = NUM_OF_LEDS_BY_LEVEL * level; i <= (NUM_OF_LEDS_BY_LEVEL * level + NUM_OF_LEDS_BY_LEVEL - 1); i++) // On éteint toutes les leds du niveau
127 {
128 leds[i] = CRGB::Black;
129 }
130 FastLED.show();
131 delay(100);
132 }
133 leds[last_point] = CRGB::Red;
134 }
135
136 void score_leds() // affichage du score avec les leds
137 {
138 for (int i = 0; i < score; i++)
139 {
140 leds[i] = CRGB::Red;
141
142 FastLED.show();
143 delay(10);
144 }
145 }
146
147 void reset_leds() // on éteint toutes les leds
148 {
149 for (int i = 0; i < NUM_LEDS; i++)
150 {
151 leds[i] = CRGB::Black;
152
153 }
154 FastLED.show();
155 }
156
157 void animation_attente()
158 {
159 for(int i = 0; i < NUM_LEDS; i++)
160 {
161 leds[i].red = random(0,255);
162 leds[i].green = random(0,255);
163 leds[i].blue = random(0,255);
164 }
165 FastLED.show();
166
167 }
168 void level_up() // changement de niveau
169 {
170 flash(); // animation
171 level++; // incrémentation de la variable niveau
172 delay_level -= 4; // le jeu devient de plus en plus rapide
173 if (level >= NUM_OF_LEVELS) // fin du jeu
174 {
175 reset_leds();
176 score_leds(); // affichage score
177 delay(3000);
178 reset_leds();
179 while (!digitalRead(PIN_BTN)) // on attend que l'utilisateur appuie sur un bonton
180 {
181 animation_attente();
182 delay(200);
183 }
184 while (digitalRead(PIN_BTN)) // on vérifie que le bouton n'est pas resté appuyé
185 {
186 delay(10);
187 }
188 // on réinitialise le jeu
189 level = 0;
190 reset_leds();
191 score = 0;
192 delay_level = 30;
193
194
195 }
196
197
198 }