Components and supplies
Jumper wires (generic)
Arduino UNO
YwRobot Arduino LCM1602 IIC V1 conventer
Standard LCD - 16x2 White on Blue
Buzzer
Pushbutton switch 12mm
Apps and platforms
Arduino IDE
Project description
Code
Game code and scheme
arduino
Library: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/ Sometimes you can find polish words.
1// SCHEME 2// GND and Pin 3 - Buzzer 3// GND and Reset - button 4// GND and Pin 4 - button 5// GND and Pin 2 - button 6// --------DISPLAY--------- 7// SCL - A5 8// SDA - A4 9// GND - GND 10// VCC - 5V 11 12 13#include <LiquidCrystal_I2C.h> 14volatile int grasw; 15volatile int napis; 16volatile int podmenu; 17#define PIN_BUTTON 2 18#define PIN_AUTOPLAY 1 19#define PIN_READWRITE 10 20#define PIN_CONTRAST 12 21#define SPRITE_RUN1 1 22#define SPRITE_RUN2 2 23#define SPRITE_JUMP 3 24#define SPRITE_JUMP_UPPER '.' 25#define SPRITE_JUMP_LOWER 4 26#define SPRITE_TERRAIN_EMPTY ' ' 27#define SPRITE_TERRAIN_SOLID 5 28#define SPRITE_TERRAIN_SOLID_RIGHT 6 29#define SPRITE_TERRAIN_SOLID_LEFT 7 30#define HERO_HORIZONTAL_POSITION 1 31#define TERRAIN_WIDTH 16 32#define TERRAIN_EMPTY 0 33#define TERRAIN_LOWER_BLOCK 1 34#define TERRAIN_UPPER_BLOCK 2 35#define HERO_POSITION_OFF 0 36#define HERO_POSITION_RUN_LOWER_1 1 37#define HERO_POSITION_RUN_LOWER_2 2 38#define HERO_POSITION_JUMP_1 3 39#define HERO_POSITION_JUMP_2 4 40#define HERO_POSITION_JUMP_3 5 41#define HERO_POSITION_JUMP_4 6 42#define HERO_POSITION_JUMP_5 7 43#define HERO_POSITION_JUMP_6 8 44#define HERO_POSITION_JUMP_7 9 45#define HERO_POSITION_JUMP_8 10 46#define HERO_POSITION_RUN_UPPER_1 11 47#define HERO_POSITION_RUN_UPPER_2 12 48 49LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 50static char terrainUpper[TERRAIN_WIDTH + 1]; 51static char terrainLower[TERRAIN_WIDTH + 1]; 52static bool buttonPushed = false; 53char wybor; 54char wyborpoz; 55 56 57void initializeGraphics(){ 58 static byte graphics[] = { 59 // Run position 1 60 B01100, 61 B01100, 62 B00000, 63 B01110, 64 B11100, 65 B01100, 66 B11010, 67 B10011, 68 // Run position 2 69 B01100, 70 B01100, 71 B00000, 72 B01100, 73 B01100, 74 B01100, 75 B01100, 76 B01110, 77 // Jump 78 B01100, 79 B01100, 80 B00000, 81 B11110, 82 B01101, 83 B11111, 84 B10000, 85 B00000, 86 // Jump lower 87 B11110, 88 B01101, 89 B11111, 90 B10000, 91 B00000, 92 B00000, 93 B00000, 94 B00000, 95 // Ground 96 B11111, 97 B11111, 98 B11111, 99 B11111, 100 B11111, 101 B11111, 102 B11111, 103 B11111, 104 // Ground right 105 B00011, 106 B00011, 107 B00011, 108 B00011, 109 B00011, 110 B00011, 111 B00011, 112 B00011, 113 // Ground left 114 B11000, 115 B11000, 116 B11000, 117 B11000, 118 B11000, 119 B11000, 120 B11000, 121 B11000, 122 }; 123 int i; 124 125 126 for (i = 0; i < 7; ++i) { 127 lcd.createChar(i + 1, &graphics[i * 8]); 128 } 129 for (i = 0; i < TERRAIN_WIDTH; ++i) { 130 terrainUpper[i] = SPRITE_TERRAIN_EMPTY; 131 terrainLower[i] = SPRITE_TERRAIN_EMPTY; 132 } 133} 134 135void advanceTerrain(char* terrain, byte newTerrain){ 136 for (int i = 0; i < TERRAIN_WIDTH; ++i) { 137 char current = terrain[i]; 138 char next = (i == TERRAIN_WIDTH-1) ? newTerrain : terrain[i+1]; 139 switch (current){ 140 case SPRITE_TERRAIN_EMPTY: 141 terrain[i] = (next == SPRITE_TERRAIN_SOLID) ? SPRITE_TERRAIN_SOLID_RIGHT : SPRITE_TERRAIN_EMPTY; 142 break; 143 case SPRITE_TERRAIN_SOLID: 144 terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ? SPRITE_TERRAIN_SOLID_LEFT : SPRITE_TERRAIN_SOLID; 145 break; 146 case SPRITE_TERRAIN_SOLID_RIGHT: 147 terrain[i] = SPRITE_TERRAIN_SOLID; 148 break; 149 case SPRITE_TERRAIN_SOLID_LEFT: 150 terrain[i] = SPRITE_TERRAIN_EMPTY; 151 break; 152 } 153 } 154} 155void gl (int czas, int glos){ 156 157tone(3, glos); 158delay(czas); 159noTone(3); 160} 161 162 163bool drawHero(byte position, char* terrainUpper, char* terrainLower, unsigned int score) { 164 bool collide = false; 165 char upperSave = terrainUpper[HERO_HORIZONTAL_POSITION]; 166 char lowerSave = terrainLower[HERO_HORIZONTAL_POSITION]; 167 byte upper, lower; 168 switch (position) { 169 case HERO_POSITION_OFF: 170 upper = lower = SPRITE_TERRAIN_EMPTY; 171 break; 172 case HERO_POSITION_RUN_LOWER_1: 173 upper = SPRITE_TERRAIN_EMPTY; 174 lower = SPRITE_RUN1; 175 break; 176 case HERO_POSITION_RUN_LOWER_2: 177 upper = SPRITE_TERRAIN_EMPTY; 178 lower = SPRITE_RUN2; 179 break; 180 case HERO_POSITION_JUMP_1: 181 case HERO_POSITION_JUMP_8: 182 upper = SPRITE_TERRAIN_EMPTY; 183 lower = SPRITE_JUMP; 184 break; 185 case HERO_POSITION_JUMP_2: 186 case HERO_POSITION_JUMP_7: 187 upper = SPRITE_JUMP_UPPER; 188 lower = SPRITE_JUMP_LOWER; 189 break; 190 case HERO_POSITION_JUMP_3: 191 case HERO_POSITION_JUMP_4: 192 case HERO_POSITION_JUMP_5: 193 case HERO_POSITION_JUMP_6: 194 upper = SPRITE_JUMP; 195 lower = SPRITE_TERRAIN_EMPTY; 196 break; 197 case HERO_POSITION_RUN_UPPER_1: 198 upper = SPRITE_RUN1; 199 lower = SPRITE_TERRAIN_EMPTY; 200 break; 201 case HERO_POSITION_RUN_UPPER_2: 202 upper = SPRITE_RUN2; 203 lower = SPRITE_TERRAIN_EMPTY; 204 break; 205 } 206 if (upper != ' ') { 207 terrainUpper[HERO_HORIZONTAL_POSITION] = upper; 208 collide = (upperSave == SPRITE_TERRAIN_EMPTY) ? false : true; 209 210 } 211 if (lower != ' ') { 212 terrainLower[HERO_HORIZONTAL_POSITION] = lower; 213 collide |= (lowerSave == SPRITE_TERRAIN_EMPTY) ? false : true; 214 } 215 216 byte digits = (score > 9999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score > 9) ? 2 : 1; 217 218 // Draw the scene 219 terrainUpper[TERRAIN_WIDTH] = '\\0'; 220 terrainLower[TERRAIN_WIDTH] = '\\0'; 221 char temp = terrainUpper[16-digits]; 222 terrainUpper[16-digits] = '\\0'; 223 lcd.setCursor(0,0); 224 lcd.print(terrainUpper); 225 terrainUpper[16-digits] = temp; 226 lcd.setCursor(0,1); 227 lcd.print(terrainLower); 228 229 lcd.setCursor(16 - digits,0); 230 lcd.print(score); 231 232 terrainUpper[HERO_HORIZONTAL_POSITION] = upperSave; 233 terrainLower[HERO_HORIZONTAL_POSITION] = lowerSave; 234 return collide; 235} 236 237// Handle the button push as an interrupt 238void buttonPush() { 239 buttonPushed = true; 240 241} 242 243void poczatek(){ 244 lcd.setCursor(0,0); 245 lcd.print("Avoid it"); 246 lcd.setCursor(2,4); 247 lcd.print("And jump"); 248 249 gl(100,400); 250 gl(100,300); 251 gl(100,200); 252 gl(100,300); 253 gl(100,400); 254 gl(100,600); 255 delay(1000); 256 lcd.clear(); 257 258} 259 260void gra(int poziomgry){ 261 static byte heroPos = HERO_POSITION_RUN_LOWER_1; 262 static byte newTerrainType = TERRAIN_EMPTY; 263 static byte newTerrainDuration = 1; 264 static bool playing = false; 265 static bool blink = false; 266 static unsigned int distance = 0; 267 if (!playing) { 268 drawHero((blink) ? HERO_POSITION_OFF : heroPos, terrainUpper, terrainLower, distance >> 3); 269 if (blink) { 270 lcd.clear(); 271 lcd.setCursor(0,0); 272 lcd.print("Press JUMP"); 273 } 274 delay(250); 275 blink = !blink; 276 if (buttonPushed) { 277 gl(100,400); 278 gl(100,600); 279 gl(100,400); 280 initializeGraphics(); 281 heroPos = HERO_POSITION_RUN_LOWER_1; 282 playing = true; 283 buttonPushed = false; 284 distance = 0; 285 286 } 287 return; 288 } 289 290 // Shift the terrain to the left 291 advanceTerrain(terrainLower, newTerrainType == TERRAIN_LOWER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY); 292 advanceTerrain(terrainUpper, newTerrainType == TERRAIN_UPPER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY); 293 294 // Make new terrain to enter on the right 295 if (--newTerrainDuration == 0) { 296 if (newTerrainType == TERRAIN_EMPTY) { 297 newTerrainType = (random(3) == 0) ? TERRAIN_UPPER_BLOCK : TERRAIN_LOWER_BLOCK; 298 newTerrainDuration = 2 + random(10); 299 } else { 300 newTerrainType = TERRAIN_EMPTY; 301 newTerrainDuration = 10 + random(10); 302 } 303 } 304 305 if (buttonPushed) { 306 307 if (heroPos <= HERO_POSITION_RUN_LOWER_2) 308 gl(100,300); 309 heroPos = HERO_POSITION_JUMP_1; 310 buttonPushed = false; 311 312 } 313 314 if (drawHero(heroPos, terrainUpper, terrainLower, distance >> 3)) { 315 playing = false; // The hero collided with something. Too bad. 316 gl(100,500); 317 gl(100,400); 318 gl(120,300); 319 gl(160,400); 320 lcd.clear(); 321 } else { 322 if (heroPos == HERO_POSITION_RUN_LOWER_2 || heroPos == HERO_POSITION_JUMP_8) { 323 heroPos = HERO_POSITION_RUN_LOWER_1; 324 } else if ((heroPos >= HERO_POSITION_JUMP_3 && heroPos <= HERO_POSITION_JUMP_5) && terrainLower[HERO_HORIZONTAL_POSITION] != SPRITE_TERRAIN_EMPTY) { 325 heroPos = HERO_POSITION_RUN_UPPER_1; 326 } else if (heroPos >= HERO_POSITION_RUN_UPPER_1 && terrainLower[HERO_HORIZONTAL_POSITION] == SPRITE_TERRAIN_EMPTY) { 327 heroPos = HERO_POSITION_JUMP_5; 328 } else if (heroPos == HERO_POSITION_RUN_UPPER_2) { 329 heroPos = HERO_POSITION_RUN_UPPER_1; 330 } else { 331 ++heroPos; 332 } 333 ++distance; 334 335 digitalWrite(PIN_AUTOPLAY, terrainLower[HERO_HORIZONTAL_POSITION + 2] == SPRITE_TERRAIN_EMPTY ? HIGH : LOW); 336 } 337 delay(poziomgry); 338 } 339 340void setup(){ 341 pinMode(4, INPUT_PULLUP); 342 pinMode(3, OUTPUT); 343 pinMode(PIN_BUTTON, INPUT); 344 digitalWrite(PIN_BUTTON, HIGH); 345 napis = 1; 346 347 attachInterrupt(0/*PIN_BUTTON*/, buttonPush, FALLING); 348 349 initializeGraphics(); 350 351 lcd.begin(16, 2); 352 poczatek(); 353 do{menu();}while(digitalRead(2) == HIGH); 354 355 356} 357 358 359void loop() { 360switch (grasw) { 361case 1: 362gra(70); 363break; 364case 2: 365gra(50); 366break; 367case 3: 368gra(15); 369break; 370case 4: 371gra(1); 372break; 373 } 374 } 375 376void menu() { 377 378if (napis > 4 || napis < 0) {napis == 0;} 379if (digitalRead(4) == LOW) { napis++;} 380 switch (napis) { 381 382 case 1: 383 lcd.setCursor(0,0); 384 lcd.print("Select mode:"); 385 lcd.setCursor(0,1); 386 lcd.print("< Easy >"); 387 delay(500); 388 lcd.clear(); 389 lcd.setCursor(0,0); 390 lcd.print("Select mode:"); 391 lcd.setCursor(0,1); 392 lcd.print("< >"); 393 delay(500); 394 if(digitalRead(2) == LOW) { 395 grasw = 1; 396 grasw;} 397 398 break; 399 case 2: 400lcd.setCursor(0,0); 401 lcd.print("Select mode:"); 402 lcd.setCursor(0,1); 403 lcd.print("< Medium >"); 404 delay(500); 405 lcd.clear(); 406 lcd.setCursor(0,0); 407 lcd.print("Select mode:"); 408 lcd.setCursor(0,1); 409 lcd.print("< >"); 410 delay(500); 411if(digitalRead(2) == LOW) { 412 grasw = 2; 413 grasw;} 414 break; 415 416 case 3: 417lcd.setCursor(0,0); 418 lcd.print("Select mode:"); 419 lcd.setCursor(0,1); 420 lcd.print("< Hard >"); 421 delay(500); 422 lcd.clear(); 423 lcd.setCursor(0,0); 424 lcd.print("Select mode:"); 425 lcd.setCursor(0,1); 426 lcd.print("< >"); 427 delay(500); 428 if(digitalRead(2) == LOW) { 429 grasw = 3; 430 grasw;} 431 432 break; 433 case 4: 434lcd.setCursor(0,0); 435 lcd.print("Select mode:"); 436 lcd.setCursor(0,1); 437 lcd.print("< impossible >"); 438 delay(500); 439 lcd.clear(); 440 lcd.setCursor(0,0); 441 lcd.print("Select mode:"); 442 lcd.setCursor(0,1); 443 lcd.print("< >"); 444 delay(500); 445 if(digitalRead(2) == LOW) { 446 grasw = 4; 447 grasw;} 448 break; 449 450 default: 451napis = 0; 452 break; 453 } 454 } 455 456 457
Comments
Only logged in users can leave comments
Iron_Salsa
0 Followers
•0 Projects
Table of contents
Intro
38
0