Components and supplies
1
RGB LCD Shield Kit, 16x2 Character Display
2
Breadboard (generic)
1
Arduino UNO
2
Single Turn Potentiometer- 10k ohms
1
Pushbutton Switch, Momentary
1
Buzzer
1
Resistor 10k ohm
Project description
Code
Hard-Dino Game, By JY and Antonin Subiger
c_cpp
This is a small game on a 2 lines LCD screen. Help the Dino to jump over the cactus while avoiding the nasty birds. Just push the pushbutton
1/* the Hard Dino Game 2by Jean-Yves Subiger and my son Antonin Subiger 3France 413 Nov 2022 5*/ 6 7#include <LiquidCrystal.h> // Librairie pour ecran LCD 8 9LiquidCrystal ecran(12, 11, 5, 4, 3, 2); 10int PosAnt [16] [2]; // Position des obstacles ( Tableau ) 11bool BoutonLache = false; // Vrai si l'interupteur a été laché 12int Inter = 0; // etat de l'interupteur High ou low 13int LigBonh =1; // Ligne du bonhomme 0 ou 1 14int II = 0; // Index du tableau 15int LL = 0; 16int Fix = 500; // Durée en miliseconde où tout est fixé, rien ne bouge = vitesse du jeu 17int ColBonh = 1; // Constante, Numero de colonen du bonhomme, toujour 1 18int EspaceAl = 8; // Ecart initial entre 2 obstacles 19int Espace =0; // Nombre de décallage depuis l'introduction du dernier obstacle 20int Vie =3; // Nombre de vie 21long InterAugVitess = 20000; 22int Reduit =0; 23int InterReduit=0; 24unsigned long MeilleurScore=0; 25unsigned long Score=0; 26unsigned long DepartScore =0; 27unsigned long DepartSaut =0; // moment de départ du sut 28unsigned long DecalObs =0; // Moment du dernier décallage des obstacles 29 30byte oiseau[8] ={ 31 0b00001, 32 0b00010, 33 0b01101, 34 0b10110, 35 0b01111, 36 0b00010, 37 0b00000, 38 0b00000, 39}; 40 41byte personnage[8] ={ 42 0b01110, 43 0b01011, 44 0b01111, 45 0b00110, 46 0b10110, 47 0b11111, 48 0b01110, 49 0b01010, 50} ; 51 52byte cactus1[8] ={ 53 0b00100, 54 0b00101, 55 0b10101, 56 0b10111, 57 0b10100, 58 0b11100, 59 0b00100, 60 0b00100, 61}; 62 63byte cactus2[8] = { 64 0b00100, 65 0b00101, 66 0b10101, 67 0b10111, 68 0b11100, 69 0b00101, 70 0b00111, 71 0b00100, 72}; 73 74byte coeur[8]={ 75 0b01010, 76 0b11111, 77 0b11111, 78 0b11111, 79 0b01110, 80 0b00100, 81 0b00000, 82 0b00000, 83}; 84 85byte coeurvide[8]={ 86 0b01010, 87 0b10101, 88 0b10001, 89 0b10001, 90 0b01010, 91 0b00100, 92 0b00000, 93 0b00000, 94}; 95 96byte mort[8]={ 97 0b01000, 98 0b01001, 99 0b00101, 100 0b00110, 101 0b00100, 102 0b01110, 103 0b01011, 104 0b11111, 105}; 106 107void PauseBouton() { 108 Inter = digitalRead(7); 109 while (Inter == LOW) { // Pour attendre que le joueur appuie sur le bouton 110 Inter = digitalRead(7); // Detecter appuie sur le bouton 111 } 112 while (Inter == HIGH) { // Pour attendre que le joueur relache le bouton 113 Inter = digitalRead(7); // Lit la position du bouton 114 } 115} 116 117void setup() { 118 Serial.begin(9600); 119 ecran.createChar(0, personnage); // définition du personnage 120 ecran.createChar(1, cactus1); 121 ecran.createChar(2, cactus2); 122 ecran.createChar(3, oiseau); 123 ecran.createChar(4, coeur); 124 ecran.createChar(5, coeurvide); 125 ecran.createChar(7, mort); 126 pinMode(7, INPUT); // Branchement interupteur pour sauter 127 ecran.begin(16,2); 128 } // end of vset up, Fin de la boucle void 129 130void loop() { 131 ecran.clear(); // to clear the screen, Pour effacer l'écran 132 ecran.setCursor(1, 0) ; 133 ecran.print("Hard Dinos Game"); 134 ecran.setCursor(1, 1); 135 ecran.print("Push To Start !"); 136 PauseBouton(); 137 138 if (MeilleurScore <1 ) { // Display instruction for the first game only 139 ecran.setCursor(0, 1) ; 140 ecran.print("Avoid "); 141 ecran.setCursor(7, 1); 142 ecran.write(1); 143 ecran.setCursor(9, 1); 144 ecran.write(2); 145 ecran.setCursor(11, 1); 146 ecran.write(3); 147 PauseBouton(); 148 } 149 150 ecran.clear(); 151 for (II=1; II<4; II++) { // give the start to play 152 ecran.setCursor(3*II+1,0); 153 ecran.print("Go"); 154 tone(8, 400 , 300 ); 155 delay(500); 156 } 157 ecran.clear(); 158 tone(8, 600 , 500 ); 159 ecran.setCursor(13, 0); // Affichage des vies, coeurs pleins 160 ecran.write(byte(4)); 161 ecran.setCursor(14, 0); 162 ecran.write(byte(4)); 163 ecran.setCursor(15, 0); 164 ecran.write(byte(4)); 165 166 for (LL=0; LL<2; LL++) { // reset the table, Initialisation du tableau 167 for (II=0; II<16; II++) { 168 PosAnt[II][LL] =0; 169 } 170 } 171 PosAnt[15] [1] = 1; // premier obstacle 172 DecalObs = millis(); // Memorisation 173 DepartScore = millis(); 174 175 while (Vie > 0) { 176 177 // 1- obstacles review 178 if (millis()-DecalObs > Fix) { // Gestion et affichage des obstacles si pause termine 179 DecalObs = millis(); 180 // 1.1 Move the obstacle to the left 181 for (LL=0; LL<2; LL++) { // Décallage des obsacles vers la gauche 182 for (II=0; II<15; II++) { 183 PosAnt[II] [LL]= PosAnt[II+1][LL]; // Décallage des obsacles vers la gauche 184 } 185 } 186 PosAnt[15][1]=0; 187 PosAnt[15][0]=0; 188 Espace++; 189 // 1.2 Add a new obstacle on the right 190 if (Espace == EspaceAl) { // 1.1 Pour afficher un nouvel obstacle de façon aleatoire 191 // nouvel obstacle en bas 192 if (random(1,10) >2) { 193 // Alros on fait apparaitre un obstacle en haut 194 if (random(1,10) >5) { 195 PosAnt[15][1]=1; 196 } 197 else { 198 PosAnt[15][1]=2; 199 } // fin else 200 } 201 else { 202 // Sinon on fait apparatire un obstacle en bas 203 PosAnt[15][0]=3; 204 } //fin else (random(1,10) >2) 205 EspaceAl=random(3,8-Reduit); // Nouvelle Longueur aleatoire entre 2 obstacles 206 Espace=0; 207 } // if (Espace == EspaceAl) 208 // 1.3 Display the obstacles 209 for (LL=0; LL<2; LL++) { // 1.2 Affichage de tous les obstacles de la colonne 0 à 15 210 for (II=0; II<16; II++) { 211 ecran.setCursor(II, LL); 212 if (PosAnt[II][LL] > 0) { ecran.write(PosAnt[II][LL]); } // si tableau des positions =1 ou 2 alors on affiche un obstacle 213 else { // sinon on efface 214 if (II != ColBonh ) { // Pour ne pas effacer le bonhomme 215 ecran.print(" "); 216 } 217 else { // Pour effacer quand le bonhomme est en haut 218 // on est sur la colonne du bonhomme 219 if (LL==1 && LigBonh == 0 ){ecran.print(" ");} 220 if (LL==0 && LigBonh == 1 ){ecran.print(" ");} 221 } 222 } 223 } // fin for II 224 } // Fin for LL affiche obstacles 225 } // Fin de la gestion et affichage des obstacles 226 227 // 2- Check if we need to start to jump 228 Inter = digitalRead(7); // Lit l'entrée 7 de la carte, le bouton poussoir 229 if (Inter == HIGH && LigBonh == 1 && BoutonLache == true) { // 2) Debut du saut 230 DepartSaut = millis(); // Reset jump time 231 BoutonLache = false; 232 LigBonh = 0; // le bonhome va sur la ligne du haut (0) 233 ecran.setCursor(ColBonh,1); 234 ecran.print(" "); // Pour effacer le bonhomme sur la ligne du bas 235 tone(8,440,20); // haut parleur brancher en 8, note LA pendant 20 ms 236 } 237 238 // 3- Check if end of jump 239 if (millis()-DepartSaut>3*Fix && LigBonh == 0) { // 3) Verifie la fin du saut 240 LigBonh = 1; // Le bonhomme va sur la ligne du bas (1) 241 ecran.setCursor(ColBonh,0); 242 ecran.print(" "); // Pour effacer le bonhomme sur la ligne du haut 243 } 244 245 // 4- Write the dinosaure on line "LigBonh" 246 ecran.setCursor(ColBonh,LigBonh); 247 ecran.write(byte(0)); // Ecrit le bonhomme sur la ligne du haut ou du bas 248 249 // 5 250 if (Inter == LOW && LigBonh == 1) { BoutonLache=true; } // Pour ne pas que le joueur puisse laisser le bouton enfoncé tout le temps 251 252 // 6- Check if one accident on top or bottom line 253 if ((PosAnt[ColBonh][1] >0 && LigBonh == 1) || (PosAnt[ColBonh][0] >0 && LigBonh == 0) ) { // 4) Obstacle sur la meme colone que le bonhome et bonhome en bas : predu 254 Vie--; // Perdu, une vie en moins 255 ecran.setCursor(0, 0); 256 ecran.print(" Oups !!"); 257 for (II=0; II< Vie; II++) { 258 ecran.setCursor(15-II, 0); // Affichage des vies, coeurs pleins 259 ecran.write(byte(4)); 260 } 261 ecran.setCursor(15-Vie, 0); 262 ecran.write(5); // Affiche le coeur vide 263 ecran.setCursor(1, 1); 264 ecran.write(byte(7)); // Display dead Dino, Affiche le mort 265 Fix = 500 ; // the speed is reset to the inital value but not the distance betwwen obstacles. La vitesse reprend plus lentement 266 for (II=550; II>300; II--) { // Option pour Bruitage buzer 267 tone(8,II,10); // Option pour Bruitage buzer 268 delay(5); // Option pour Bruitage buzer 269 } // Option pour Bruitage buzer 270 noTone(8); // Option pour Bruitage buzer 271 delay(500); 272 ecran.setCursor(15-Vie, 0); 273 ecran.print(" "); 274 ecran.setCursor(0, 0); 275 ecran.print(" "); 276 ecran.setCursor(1, 1); 277 ecran.write(byte(0)); // Display normal dino 278 } // Fin perdu 279 280 // 7- Check if speed must be increase 281 if (millis() - DepartScore > InterAugVitess ){ // 5) Pour augmenter la vitesse du jeu regulierement 282 Fix -= 30; // How much the speed increase 283 InterAugVitess += 20000; // How often the speed increase 284 InterReduit++; 285 if (InterReduit>2 && Reduit <4 ) { // How often and how small the length between each obstacler become 286 InterReduit=0; 287 Reduit++; // EspaceAl=random(3,8-Reduit); 288 } 289 tone(8, 800 , 600 ); 290 } 291 } // while (Vie > 0) 292 293 // End of one game 294 ecran.clear(); 295 ecran.setCursor(3, 0); 296 ecran.print("GAME OVER"); 297 ecran.setCursor(0, 1); 298 ecran.print("Score: "); 299 ecran.setCursor(8, 1); 300 Score = millis() - DepartScore; 301 ecran.print(Score); 302 PauseBouton(); 303 304 if ( MeilleurScore > 0) { 305 ecran.clear(); 306 if ( Score > MeilleurScore) { 307 ecran.setCursor(3, 1); 308 ecran.print(Score); 309 MeilleurScore = Score; 310 Inter=LOW; 311 while (Inter == LOW) { 312 Inter = digitalRead(7); 313 ecran.setCursor(0, 0); 314 ecran.print("New Best Score !!"); 315 DepartSaut=millis(); 316 while (millis()-DepartSaut<300 && Inter == LOW ) { 317 Inter = digitalRead(7); 318 } 319 ecran.setCursor(0, 0); 320 ecran.print(" "); 321 DepartSaut=millis(); 322 while (millis()-DepartSaut<300 && Inter == LOW ) { 323 Inter = digitalRead(7); 324 } 325 } 326 } 327 else { 328 ecran.setCursor(0, 1); 329 ecran.print("Your: "); 330 ecran.setCursor(6, 1); 331 ecran.print(Score); 332 ecran.setCursor(0, 0); 333 ecran.print("Best: "); 334 ecran.setCursor(6, 0); 335 ecran.print(MeilleurScore); 336 } 337 PauseBouton(); 338 } 339 else { 340 MeilleurScore = Score; 341 } 342 // Reset the value before to testart the new game 343 Vie = 3; 344 EspaceAl = 8; 345 Espace = 0; 346 Fix = 500; 347 InterAugVitess = 20000; 348 Reduit = 0; 349 InterReduit=0; 350 Score = 0; 351 352}// fin void loop 353 354 355
Downloadable files
Schematics and circuit diagrams
To connect the screen and the potentiometers
Schematics and circuit diagrams

Comments
Only logged in users can leave comments