In questo tutorial vedremo in che modo creare un gioco interattivo con Arduino.
Snake è un videogioco presente in molti telefonini, in particolare quelli prodotti dalla Nokia. Le sue origini risalgono agli anni settanta, con il videogioco arcade Blockade; da allora è stato prodotto in numerose piattaforme e varianti, fino a ritrovare nuova fama negli anni novanta grazie ai cellulari.
Basta con le chiacchiere, arriviamo subito al sodo.
I materiali da utilizzare per il collegamento del display TFT 1,8″ alla board Arduino sono:
- Arduino Uno
- Display TFT
- Cavo USB
- 1x breadboard
- 4x bottoni
- 4x resistenza da 10K Ohm
COLLEGAMENTO
Ci sono tantissimi display TFT da 1,8″ nel mercato, quindi il collegamento potrebbe cambiare da display a display. I display possono avere la posizioni di alcuni pin differente ma comunque sono presenti le “stesse sigle” che permettono quindi di effettuare correttamente il collegamento prendendo anche come riferimento altri display con la posizione dei pin diversa. Rispetto a questo display ce ne potrebbero essere altri con pin BLK (blacklight), che in questo caso non è presente, ma niente di preoccuparsi, lo puoi collegare al pin 12.
Se è la prima volta che utilizzi il display, prima di scrivere il codice ti consiglio vivamente di leggere questo articolo introduttivo sul collegamento e configurazione del display ST7735 TFT 1,8″
Come collegare display TFT 1,8″ ST7735 ad Arduino
Ecco il diagramma di collegamento:
CODICE
Ecco qui il codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
#include <SPI.h> #include <TFT.h> struct colour_struct{ int r; int g; int b; }; typedef struct colour_struct colour; colour bgCol = {93,200,255}; colour snakeCol = {245, 78, 253}; colour foodCol = {253,230,62}; /* TFT pins */ #define LCD_CS 10 #define SD_CS 4 #define DC 9 #define RESET 8 /* Pushbutton pins */ #define PBLEFT 7 #define PBDOWN 6 #define PBUP 3 #define PBRIGHT 2 #define screenWidth 160 #define screenHeight 128 #define tileSize 6 TFT screen = TFT(LCD_CS, DC, RESET); long timestamp = 0; int score = 0; int collision = 0; int goX = 0; int goY = 0; struct coord_struct{ int x; int y; struct coord_struct *next_ptr; }; typedef struct coord_struct coord; coord *new_ptr; coord *temp; coord *head = NULL; struct { int x; int y; int growBy; } food; /***************************************************************** * FUNCTIONS */ void addFirst(int x, int y){ new_ptr = (coord *)malloc(sizeof(coord)); new_ptr->x = x; new_ptr->y = y; new_ptr->next_ptr = head; head = new_ptr; } void remLast(){ coord *last; temp = head; last = temp; while (temp != NULL && temp->next_ptr != NULL){ last = temp; temp = temp->next_ptr; } if (last == temp){ free(temp); head = NULL; } else { drawRect(temp->x,temp->y,&bgCol); /* draw */ free(last->next_ptr); last->next_ptr = NULL; } } void startScreen(){ reset(); screen.background(245, 78, 253); screen.setTextSize(4); screen.stroke(0,255,0); screen.text("Snake",10,10); screen.setTextSize(1); screen.text("press button to start",10, 80); while (goX == 0 && goY == 0){ getInput(); delay(5); } screen.stroke(0,0,0); screen.fill(bgCol.r,bgCol.g,bgCol.b); screen.rect(3,2,screenWidth-6,screenHeight-4); for (int i = 29; i<=53; i+=6){ addFirst(i,52); drawRect(head->x, head->y,&snakeCol); } putFood(); } void reset(){ goX = 0; goY = 0; collision = 0; score = 0; while(head){ remLast(); } } void getInput(){ if (digitalRead(PBLEFT) == HIGH){ goX = -tileSize; goY = 0; } else if (digitalRead(PBDOWN) == HIGH){ goX = 0; goY = tileSize; } else if (digitalRead(PBUP) == HIGH){ goX = 0; goY = -tileSize; } else if (digitalRead(PBRIGHT) == HIGH){ goX = tileSize; goY = 0; } } int isGrow(){ if(head->x == food.x && head->y == food.y){ return 1; } else { return 0; } } int isCollision(){ temp = head->next_ptr; while(temp){ if (temp->x == head->x && temp->y == head->y){ return 1; } temp = temp->next_ptr; } if(head->x < 5 || head->x > 149 || head->y < 4 || head->y > 118){ return 1; } return 0; } void putFood(){ int validPlace = 0; while (!validPlace){ food.x = 5 + (int)random(0,24)*6; food.y = 4 + (int)random(0,19)*6; if (food.x != head->x && food.y != head->y){ validPlace = 1; } } drawRect(food.x, food.y, &foodCol); } void drawRect(int x, int y, colour *c){ screen.noStroke(); screen.fill(c->r, c->g, c->b); screen.rect(x,y,tileSize,tileSize); } void endScreen(){ char scoreChars[5]; screen.background(0, 255, 0); screen.stroke(255,255,255); String scorestring = String(score); scorestring.toCharArray(scoreChars,5); screen.text("Game over", 40, 40); screen.text("Score:", 40, 50); screen.text(scoreChars, 80, 50); delay(1000); } void setup(){ screen.begin(); randomSeed(analogRead(0)); } void loop(){ startScreen(); while (!collision){ getInput(); delay(5); if (millis()-timestamp > 200){ addFirst((head->x + goX), (head->y + goY)); drawRect(head->x,head->y,&snakeCol); if (food.growBy){ food.growBy--; score += 1; } else { remLast(); } if (isGrow()){ food.growBy++; putFood(); } if (isCollision()){ collision = 1; } timestamp = millis(); } } endScreen(); } |
Carica il codice e inizia a giocare!
Conclusione
Voglio ringraziare AZ-Delivery per avermi dato la possibilità di avere il display.
Preferireste aspettare 8 settimane per l’autoimportazione dalla Cina, incerti se le merci arriveranno mai, le terre alla dogana o semplicemente saranno rispedite indietro? O acquistare in Germania ad un prezzo totalmente gonfiato da un rivenditore specializzato? Preferisci acquistare il prodotto a buon mercato in Cina senza essere sicuro di quale versione del prodotto riceverai, o ordinarlo dal rivenditore tedesco incl. istruzioni e scheda dati?
Nel seguente link è presente il sito ufficiale AZdelivery
Iscriviti ai nostri gruppi Telegram
Link utili
Ciao Simone. Come hai fatto a realizzare questo gioco. Io ho provato con la libreria Adafruit ST7735s ma il refresh dello screen ad ogni loop è lentissimo. In pratica vado molto sotto i 30 FPS (frame per seconds) necessari per rendere il gioco fluido. La frequenza di aggiornamento dei pixel mi sembra molto bassa. Mi potresti dare una dritta???