Guest User

Codice Arduino game

a guest
Jun 17th, 2026
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.57 KB | None | 0 0
  1. #include <LiquidCrystal.h>
  2.  
  3. #define PIN_BUTTON 2
  4. #define PIN_AUTOPLAY 1
  5. #define PIN_READWRITE 10
  6. #define PIN_CONTRAST 12
  7.  
  8. #define SPRITE_RUN1 1
  9. #define SPRITE_RUN2 2
  10. #define SPRITE_JUMP 3
  11. #define SPRITE_JUMP_UPPER '.'
  12. #define SPRITE_JUMP_LOWER 4
  13. #define SPRITE_TERRAIN_EMPTY ' '
  14. #define SPRITE_TERRAIN_CACTUS 5
  15. #define SPRITE_TERRAIN_CACTUS_RIGHT 6
  16. #define SPRITE_TERRAIN_CACTUS_LEFT 7
  17.  
  18. #define DINO_HORIZONTAL_POSITION 1
  19.  
  20. #define TERRAIN_WIDTH 16
  21. #define TERRAIN_EMPTY 0
  22. #define TERRAIN_LOWER_BLOCK 1
  23. #define TERRAIN_UPPER_BLOCK 2
  24.  
  25. #define DINO_POSITION_OFF 0
  26. #define DINO_POSITION_RUN_LOWER_1 1
  27. #define DINO_POSITION_RUN_LOWER_2 2
  28. #define DINO_POSITION_JUMP_1 3
  29. #define DINO_POSITION_JUMP_2 4
  30. #define DINO_POSITION_JUMP_3 5
  31. #define DINO_POSITION_JUMP_4 6
  32. #define DINO_POSITION_JUMP_5 7
  33. #define DINO_POSITION_JUMP_6 8
  34. #define DINO_POSITION_JUMP_7 9
  35. #define DINO_POSITION_JUMP_8 10
  36. #define DINO_POSITION_RUN_UPPER_1 11
  37. #define DINO_POSITION_RUN_UPPER_2 12
  38.  
  39. LiquidCrystal lcd(11, 9, 6, 5, 4, 3);
  40.  
  41. static char terrainUpper[TERRAIN_WIDTH + 1];
  42. static char terrainLower[TERRAIN_WIDTH + 1];
  43. static bool buttonPushed = false;
  44.  
  45. void fireworks() {
  46. lcd.clear();
  47. lcd.setCursor(3, 0); lcd.print("* * *");
  48. lcd.setCursor(2, 1); lcd.print(" * * ");
  49. delay(200);
  50. lcd.clear();
  51. lcd.setCursor(5, 0); lcd.print("\\ | /");
  52. lcd.setCursor(5, 1); lcd.print("/ | \\");
  53. delay(200);
  54. lcd.clear();
  55. lcd.setCursor(4, 0); lcd.print("* * * *");
  56. lcd.setCursor(3, 1); lcd.print(" * * * ");
  57. delay(200);
  58. lcd.clear();
  59. }
  60.  
  61. void showLevelMessage(unsigned int score) {
  62. lcd.clear();
  63. if(score == 10) lcd.print("BRAVO!");
  64. else if(score == 20) lcd.print("BRAVISSIMO!");
  65. else if(score == 30) lcd.print("ECCELLENTE!");
  66. else if(score == 40) lcd.print("CONTINUA COSI");
  67. delay(1500);
  68. lcd.clear();
  69. }
  70.  
  71. void initializeGraphics() {
  72. static byte graphics[] = {
  73. B00111, B00111, B10111, B11100, B11111, B01100, B01000, B00000,
  74. B00111, B00111, B10111, B11100, B11111, B01100, B00010, B00000,
  75. B00111, B00111, B10111, B11100, B11111, B01100, B00000, B00000,
  76. B11100, B11111, B01100, B01010, B00000, B00000, B00000, B00000,
  77. B00100, B00101, B10101, B01111, B00100, B00100, B00100, B00000,
  78. B00001, B00001, B00101, B00111, B00001, B00001, B00001, B00000,
  79. B10000, B10000, B10100, B11100, B10000, B10000, B10000, B00000
  80. };
  81. for (int i = 0; i < 7; ++i)
  82. lcd.createChar(i + 1, &graphics[i * 8]);
  83.  
  84. for (int i = 0; i < TERRAIN_WIDTH; ++i) {
  85. terrainUpper[i] = SPRITE_TERRAIN_EMPTY;
  86. terrainLower[i] = SPRITE_TERRAIN_EMPTY;
  87. }
  88. }
  89.  
  90. void advanceTerrain(char* terrain, byte newTerrain) {
  91. for (int i = 0; i < TERRAIN_WIDTH; ++i) {
  92. char current = terrain[i];
  93. char next = (i == TERRAIN_WIDTH - 1) ? newTerrain : terrain[i + 1];
  94. switch (current) {
  95. case SPRITE_TERRAIN_EMPTY:
  96. terrain[i] = (next == SPRITE_TERRAIN_CACTUS) ? SPRITE_TERRAIN_CACTUS_RIGHT : SPRITE_TERRAIN_EMPTY;
  97. break;
  98. case SPRITE_TERRAIN_CACTUS:
  99. terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ? SPRITE_TERRAIN_CACTUS_LEFT : SPRITE_TERRAIN_CACTUS;
  100. break;
  101. case SPRITE_TERRAIN_CACTUS_RIGHT:
  102. terrain[i] = SPRITE_TERRAIN_CACTUS;
  103. break;
  104. case SPRITE_TERRAIN_CACTUS_LEFT:
  105. terrain[i] = SPRITE_TERRAIN_EMPTY;
  106. break;
  107. }
  108. }
  109. }
  110.  
  111. bool drawDino(byte position, char* terrainUpper, char* terrainLower, unsigned int score) {
  112. bool collide = false;
  113. char upperSave = terrainUpper[DINO_HORIZONTAL_POSITION];
  114. char lowerSave = terrainLower[DINO_HORIZONTAL_POSITION];
  115. byte upper, lower;
  116. switch (position) {
  117. case DINO_POSITION_OFF: upper = lower = SPRITE_TERRAIN_EMPTY; break;
  118. case DINO_POSITION_RUN_LOWER_1: upper = SPRITE_TERRAIN_EMPTY; lower = SPRITE_RUN1; break;
  119. case DINO_POSITION_RUN_LOWER_2: upper = SPRITE_TERRAIN_EMPTY; lower = SPRITE_RUN2; break;
  120. case DINO_POSITION_JUMP_1:
  121. case DINO_POSITION_JUMP_8: upper = SPRITE_TERRAIN_EMPTY; lower = SPRITE_JUMP; break;
  122. case DINO_POSITION_JUMP_2:
  123. case DINO_POSITION_JUMP_7: upper = SPRITE_JUMP_UPPER; lower = SPRITE_JUMP_LOWER; break;
  124. case DINO_POSITION_JUMP_3:
  125. case DINO_POSITION_JUMP_4:
  126. case DINO_POSITION_JUMP_5:
  127. case DINO_POSITION_JUMP_6: upper = SPRITE_JUMP; lower = SPRITE_TERRAIN_EMPTY; break;
  128. case DINO_POSITION_RUN_UPPER_1: upper = SPRITE_RUN1; lower = SPRITE_TERRAIN_EMPTY; break;
  129. case DINO_POSITION_RUN_UPPER_2: upper = SPRITE_RUN2; lower = SPRITE_TERRAIN_EMPTY; break;
  130. }
  131. if (upper != ' ') {
  132. terrainUpper[DINO_HORIZONTAL_POSITION] = upper;
  133. collide = (upperSave != SPRITE_TERRAIN_EMPTY);
  134. }
  135. if (lower != ' ') {
  136. terrainLower[DINO_HORIZONTAL_POSITION] = lower;
  137. collide |= (lowerSave != SPRITE_TERRAIN_EMPTY);
  138. }
  139. byte digits = (score > 9999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score > 9) ? 2 : 1;
  140. terrainUpper[TERRAIN_WIDTH] = '\0';
  141. terrainLower[TERRAIN_WIDTH] = '\0';
  142. char temp = terrainUpper[16 - digits];
  143. terrainUpper[16 - digits] = '\0';
  144. lcd.setCursor(0, 0);
  145. lcd.print(terrainUpper);
  146. terrainUpper[16 - digits] = temp;
  147. lcd.setCursor(0, 1);
  148. lcd.print(terrainLower);
  149. lcd.setCursor(16 - digits, 0);
  150. lcd.print(score);
  151. terrainUpper[DINO_HORIZONTAL_POSITION] = upperSave;
  152. terrainLower[DINO_HORIZONTAL_POSITION] = lowerSave;
  153. return collide;
  154. }
  155.  
  156. void buttonPush() {
  157. buttonPushed = true;
  158. }
  159.  
  160. void setup() {
  161. pinMode(PIN_READWRITE, OUTPUT); digitalWrite(PIN_READWRITE, LOW);
  162. pinMode(PIN_CONTRAST, OUTPUT); digitalWrite(PIN_CONTRAST, LOW);
  163. pinMode(PIN_BUTTON, INPUT); digitalWrite(PIN_BUTTON, HIGH);
  164. pinMode(PIN_AUTOPLAY, OUTPUT); digitalWrite(PIN_AUTOPLAY, HIGH);
  165. attachInterrupt(0, buttonPush, FALLING);
  166. initializeGraphics();
  167. lcd.begin(16, 2);
  168. lcd.clear();
  169. lcd.setCursor(2, 0); lcd.print("CALAM CFP");
  170. delay(1500);
  171. lcd.clear(); lcd.setCursor(4, 0); lcd.print("INIZIA!");
  172. delay(1200);
  173. lcd.clear();
  174. }
  175.  
  176. void loop() {
  177. static byte dinoPos = DINO_POSITION_RUN_LOWER_1;
  178. static byte newTerrainType = TERRAIN_EMPTY;
  179. static byte newTerrainDuration = 1;
  180. static bool playing = false;
  181. static bool blink = false;
  182. static unsigned int distance = 0;
  183.  
  184. if (!playing) {
  185. drawDino((blink) ? DINO_POSITION_OFF : dinoPos, terrainUpper, terrainLower, distance >> 3);
  186. blink = !blink; delay(250);
  187. if (buttonPushed) { initializeGraphics(); dinoPos = DINO_POSITION_RUN_LOWER_1; playing = true; buttonPushed = false; distance = 0; }
  188. return;
  189. }
  190.  
  191. advanceTerrain(terrainLower, newTerrainType == TERRAIN_LOWER_BLOCK ? SPRITE_TERRAIN_CACTUS : SPRITE_TERRAIN_EMPTY);
  192. advanceTerrain(terrainUpper, newTerrainType == TERRAIN_UPPER_BLOCK ? SPRITE_TERRAIN_CACTUS : SPRITE_TERRAIN_EMPTY);
  193.  
  194. if (--newTerrainDuration == 0) {
  195. if (newTerrainType == TERRAIN_EMPTY) { newTerrainType = (random(3) == 0) ? TERRAIN_UPPER_BLOCK : TERRAIN_LOWER_BLOCK; newTerrainDuration = 2 + random(10); }
  196. else { newTerrainType = TERRAIN_EMPTY; newTerrainDuration = 10 + random(10); }
  197. }
  198.  
  199. if (buttonPushed) { if (dinoPos <= DINO_POSITION_RUN_LOWER_2) dinoPos = DINO_POSITION_JUMP_1; buttonPushed = false; }
  200.  
  201. if (drawDino(dinoPos, terrainUpper, terrainLower, distance >> 3)) {
  202. lcd.clear();
  203. lcd.setCursor(0, 0); lcd.print(" Hai perso! ");
  204. lcd.setCursor(0, 1); lcd.print(" Riprova ");
  205. delay(1500);
  206. lcd.clear();
  207. lcd.setCursor(0, 0); lcd.print("OPERATORE");
  208. lcd.setCursor(0, 1); lcd.print("INFORMATICO 2026");
  209. delay(3000);
  210. playing = false;
  211. } else {
  212. if (dinoPos == DINO_POSITION_RUN_LOWER_2 || dinoPos == DINO_POSITION_JUMP_8) dinoPos = DINO_POSITION_RUN_LOWER_1;
  213. else if ((dinoPos >= DINO_POSITION_JUMP_3 && dinoPos <= DINO_POSITION_JUMP_5) && terrainLower[DINO_HORIZONTAL_POSITION] != SPRITE_TERRAIN_EMPTY) dinoPos = DINO_POSITION_RUN_UPPER_1;
  214. else if (dinoPos >= DINO_POSITION_RUN_UPPER_1 && terrainLower[DINO_HORIZONTAL_POSITION] == SPRITE_TERRAIN_EMPTY) dinoPos = DINO_POSITION_JUMP_5;
  215. else if (dinoPos == DINO_POSITION_RUN_UPPER_2) dinoPos = DINO_POSITION_RUN_UPPER_1;
  216. else ++dinoPos;
  217.  
  218. ++distance;
  219. unsigned int score = distance >> 3;
  220. static unsigned int lastFirework = 0;
  221. if (score > 0 && score % 10 == 0 && score != lastFirework) {
  222. fireworks();
  223. showLevelMessage(score);
  224. lastFirework = score;
  225. if(lastFirework >= 40) lastFirework = 0;
  226. }
  227.  
  228. digitalWrite(PIN_AUTOPLAY, terrainLower[DINO_HORIZONTAL_POSITION + 2] == SPRITE_TERRAIN_EMPTY ? HIGH : LOW);
  229.  
  230. unsigned int speed = 160; int reduction = (distance / 120) * 8; if (reduction > 120) reduction = 120; speed = 160 - reduction;
  231. delay(speed);
  232. }
  233. }
  234.  
  235.  
Advertisement
Add Comment
Please, Sign In to add comment