├── LICENSE ├── README.md ├── gameboy_128x64.ino └── img ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── 6.jpg └── 7.jpg /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Vectozavr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GameBoy_arduino 2 | Source code of gameBoy from video on YouTube channel "Vectozavr" 3 | [![Watch the video]](https://youtu.be/5UeVOUgtkyM) 4 | 5 | This project can be run on any arduino platforms: 6 | ![Project demonstration](img/5.jpg) 7 | 8 | This project contains 3 simple games. You can switch between them by menu: 9 | ![Project demonstration](img/1.jpg) 10 | 11 | You can modify any games and make them more beautiful! 12 | ![Project demonstration](img/2.jpg) 13 | 14 | Gameboy: 15 | ![Project demonstration](img/4.jpg) 16 | 17 | Gameboy inside: 18 | ![Project demonstration](img/3.jpg) 19 | 20 | Scheme for this code: 21 | ![Project demonstration](img/7.jpg) 22 | 23 | If you want to make the same configuration: 24 | ![Project demonstration](img/6.jpg) 25 | -------------------------------------------------------------------------------- /gameboy_128x64.ino: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | Vectozavr - YouTube channel about science, experiments and programming. 3 | You can share, modify and use this code for any purpose you want :) 4 | https://www.youtube.com/c/vectozavr 5 | **************************************************************************/ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #define SCREEN_WIDTH 128 // OLED display width, in pixels 15 | #define SCREEN_HEIGHT 64 // OLED display height, in pixels 16 | 17 | // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) 18 | #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) 19 | Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 20 | 21 | #define NUMFLAKES 10 // Number of snowflakes in the animation example 22 | 23 | #define LOGO_HEIGHT 16 24 | #define LOGO_WIDTH 16 25 | 26 | #define pinX A2 // ось X джойстика 27 | #define pinY A1 // ось Y джойстика 28 | #define swPin 2 // кнопка джойстика 29 | #define ledPin 13 // светодиод на Pin 13 30 | 31 | struct Point2D { 32 | float x = 0; 33 | float y = 0; 34 | }; 35 | 36 | struct Point2D_int8_t { 37 | int8_t x; 38 | int8_t y; 39 | }; 40 | 41 | struct Segment { 42 | Point2D p1; 43 | Point2D p2; 44 | }; 45 | 46 | typedef struct obstacle { 47 | int slotSize = 37; 48 | int h = 0; 49 | int w = 8; 50 | float x = SCREEN_WIDTH + w/2; 51 | }; 52 | 53 | struct JoyStick { 54 | uint32_t t_last_pressed = millis(); 55 | int STEPS = 3968; 56 | 57 | bool button () { 58 | boolean ledState = digitalRead(swPin); 59 | digitalWrite(ledPin, !ledState); 60 | 61 | double diff = (millis() - t_last_pressed); 62 | if(!ledState && diff > 1000) { 63 | t_last_pressed = millis(); 64 | return true; 65 | } 66 | return false; 67 | } 68 | 69 | float x() { 70 | int X = analogRead(pinX); 71 | 72 | if(abs(STEPS/2 - X) > STEPS/3) 73 | return( -2.0f * (STEPS/2 - X) / STEPS ); 74 | return 0; 75 | } 76 | 77 | float y() { 78 | int Y = analogRead(pinY); 79 | 80 | if(abs(STEPS/2 - Y) > STEPS/3) 81 | return( -2.0f * (STEPS/2 - Y) / STEPS ); 82 | return 0; 83 | } 84 | }; 85 | 86 | JoyStick joyStick; 87 | 88 | void menu(int game = 0) { 89 | 90 | uint32_t t_last_select = millis(); 91 | 92 | int selectedGame = game; 93 | 94 | while(true) { 95 | 96 | draw_menu_state(selectedGame); 97 | 98 | double diff = (millis() - t_last_select); 99 | double j = joyStick.x(); 100 | Serial.println(analogRead(pinY)); 101 | if(diff > 300) { 102 | if(abs(j) > 0.01) { 103 | selectedGame = j > 0 ? ((3 + selectedGame-1) % 3) : ((selectedGame+1) % 3); 104 | t_last_select = millis(); 105 | } 106 | } 107 | 108 | if(joyStick.button()) 109 | break; 110 | } 111 | 112 | switch(selectedGame) { 113 | case 0: 114 | fps(); 115 | break; 116 | case 1: 117 | snake(); 118 | break; 119 | case 2: 120 | flappyBird(); 121 | break; 122 | } 123 | 124 | return; 125 | } 126 | 127 | static const unsigned char PROGMEM logo_bmp[] = 128 | { B00000011, B11000000, 129 | B00011100, B00111000, 130 | B00100000, B00000100, 131 | B01000000, B00000010, 132 | B10011110, B01111001, 133 | B10100001, B10001111, 134 | B11000011, B10001111, 135 | B11001111, B10011111, 136 | B10001111, B11011111, 137 | B10000110, B11011011, 138 | B11000001, B10000011, 139 | B11110011, B11000111, 140 | B01111111, B11111110, 141 | B00111111, B11111100, 142 | B00011111, B11111000, 143 | B00000011, B11000000 }; 144 | 145 | void setup() { 146 | pinMode(ledPin, OUTPUT); 147 | pinMode(pinX, INPUT); 148 | pinMode(pinY, INPUT); 149 | 150 | pinMode(swPin, INPUT); 151 | digitalWrite(swPin, HIGH); 152 | 153 | Serial.begin(9600); 154 | 155 | // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally 156 | if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 157 | Serial.println(F("SSD1306 allocation failed")); 158 | for(;;); // Don't proceed, loop forever 159 | } 160 | 161 | display.clearDisplay(); 162 | 163 | draw_logo(); 164 | display.invertDisplay(true); 165 | delay(1500); 166 | display.invertDisplay(false); 167 | display.clearDisplay(); 168 | display.display(); 169 | 170 | menu(); 171 | return; 172 | } 173 | 174 | void loop() { 175 | 176 | } 177 | 178 | void draw_menu_state(int selectedGame) { 179 | display.clearDisplay(); 180 | display.setTextColor(SSD1306_WHITE); 181 | 182 | switch(selectedGame) { 183 | case 0: 184 | display.setTextSize(2); 185 | display.setCursor(LOGO_WIDTH/2 + 15, LOGO_HEIGHT/2); 186 | display.println(F("3D game")); 187 | display.setTextSize(1); 188 | display.setCursor(LOGO_WIDTH/2 + 39, LOGO_HEIGHT/2 + 25); 189 | display.println(F("Snake")); 190 | display.setCursor(LOGO_WIDTH/2 + 35, LOGO_HEIGHT/2 + 40); 191 | display.println(F("Flappy")); 192 | break; 193 | case 1: 194 | display.setTextSize(1); 195 | display.setCursor(LOGO_WIDTH/2 + 33, LOGO_HEIGHT/2); 196 | display.println(F("3D game")); 197 | display.setTextSize(2); 198 | display.setCursor(LOGO_WIDTH/2 + 25, LOGO_HEIGHT/2 + 13); 199 | display.println(F("Snake")); 200 | display.setTextSize(1); 201 | display.setCursor(LOGO_WIDTH/2 + 35, LOGO_HEIGHT/2 + 40); 202 | display.println(F("Flappy")); 203 | break; 204 | case 2: 205 | display.setTextSize(1); 206 | display.setCursor(LOGO_WIDTH/2 + 33, LOGO_HEIGHT/2); 207 | display.println(F("3D game")); 208 | display.setCursor(LOGO_WIDTH/2 + 39, LOGO_HEIGHT/2 + 15); 209 | display.println(F("Snake")); 210 | display.setTextSize(2); 211 | display.setCursor(LOGO_WIDTH/2 + 18, LOGO_HEIGHT/2 + 30); 212 | display.println(F("Flappy")); 213 | break; 214 | } 215 | 216 | display.display(); 217 | return; 218 | } 219 | 220 | void draw_logo(void) { 221 | 222 | display.drawBitmap((display.width() - LOGO_WIDTH ) / 2, (display.height() - LOGO_HEIGHT) / 2, logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1); 223 | 224 | display.setTextSize(1); 225 | display.setTextColor(SSD1306_WHITE); 226 | display.setCursor(LOGO_WIDTH/2 + 30, LOGO_HEIGHT/2 + 35); 227 | display.println(F("Vectozavr")); 228 | 229 | display.display(); 230 | return; 231 | } 232 | 233 | void fps(void) { 234 | 235 | uint32_t tp = millis(); 236 | 237 | // Camera parameters 238 | uint8_t SEGMENTS = 32; 239 | float f_depth = 12; 240 | float f_fov = PI/2; 241 | 242 | // Player parameters 243 | Point2D P_position; 244 | P_position.x = 4.0f; 245 | P_position.y = 3.0f; 246 | float f_dir = 0; 247 | float f_walk_speed = 1.0f; 248 | float f_view_speed = 2.0f; 249 | 250 | char map1[64]; 251 | strcpy(map1, "########"); 252 | strcat(map1, "# # # #"); 253 | strcat(map1, "# # # #"); 254 | strcat(map1, "# #"); 255 | strcat(map1, "# ## #"); 256 | strcat(map1, "# ## #"); 257 | strcat(map1, "# #"); 258 | strcat(map1, "########"); 259 | 260 | while(true) { 261 | // time control 262 | double diff = (millis() - tp); 263 | tp = millis(); 264 | 265 | display.clearDisplay(); 266 | 267 | // ray-cast 268 | for(uint8_t i = 0; i < SEGMENTS; i++) { 269 | 270 | //float len = ray_cast_distance(map1, 8, 8, &P_position, f_dir + (float)f_fov*(i - SEGMENTS/2)/SEGMENTS, f_depth); 271 | 272 | //--------------------------------- 273 | // ray cast 274 | float len = 0.0001f; 275 | float dx = 0.5f; 276 | float dx_min = 0.05f; 277 | 278 | 279 | while(true) { 280 | 281 | int ray_x = (int)(P_position.x + len * cos(f_dir + (float)f_fov*(i - SEGMENTS/2)/SEGMENTS) + 0.5); 282 | int ray_y = (int)(P_position.y + len * sin(f_dir + (float)f_fov*(i - SEGMENTS/2)/SEGMENTS) + 0.5); 283 | 284 | if(ray_x >= 0 && ray_x < 8 && ray_y >= 0 && ray_y < 8) { 285 | if(map1[8*ray_y + ray_x] == '#') { 286 | if(dx > dx_min) { 287 | len -= dx; 288 | dx /= 2; 289 | } else { 290 | break; 291 | } 292 | } 293 | } 294 | 295 | len += dx; 296 | if(len >= f_depth) { 297 | break; 298 | len = f_depth; 299 | } 300 | } 301 | 302 | //--------------------------------- 303 | 304 | if(len >= f_depth) 305 | continue; 306 | 307 | int h0 = (1 - 1 / len) * SCREEN_HEIGHT / 2; 308 | int h1 = (1 + 1 / len) * SCREEN_HEIGHT / 2; 309 | 310 | if(SEGMENTS == SCREEN_WIDTH) { 311 | display.drawLine(i, h0, i, h1, SSD1306_WHITE); 312 | } else { 313 | display.fillRect(i*SCREEN_WIDTH/SEGMENTS, h0, SCREEN_WIDTH/SEGMENTS, h1-h0, SSD1306_WHITE); 314 | } 315 | } 316 | 317 | // frame per seconds 318 | uint8_t fps = (int) 1000.0f / diff; 319 | 320 | display.setTextSize(1); 321 | display.setTextColor(SSD1306_WHITE); 322 | display.setCursor(0, 0); 323 | display.print("["); 324 | display.print(P_position.x); 325 | display.print(", "); 326 | display.print(P_position.y); 327 | display.print("] : "); 328 | display.print(fps); 329 | display.println(F(" fps")); 330 | 331 | display.display(); 332 | 333 | int STEPS = 3968; 334 | 335 | float f_dx = f_walk_speed * diff/1000 * cos(f_dir) * joyStick.x(); 336 | float f_dy = f_walk_speed * diff/1000 * sin(f_dir) * joyStick.x(); 337 | 338 | P_position.x += f_dx; 339 | P_position.y += f_dy; 340 | 341 | int i_x = roundf(P_position.x); 342 | int i_y = roundf(P_position.y); 343 | 344 | if(map1[8*i_y + i_x] == '#') { 345 | P_position.x -= f_dx; 346 | P_position.y -= f_dy; 347 | } 348 | 349 | f_dir += f_view_speed * diff/1000 * joyStick.y(); 350 | 351 | // end the game 352 | if(joyStick.button()) 353 | break; 354 | } 355 | 356 | menu(0); 357 | return; 358 | } 359 | 360 | void snake(void) { 361 | 362 | uint32_t tp = millis(); 363 | uint32_t timer = 500; 364 | 365 | int8_t w = 16; 366 | int8_t h = 6; 367 | 368 | int cellSize = SCREEN_WIDTH / w; 369 | 370 | int8_t snailSize = 1; 371 | int8_t dir = 1; 372 | Point2D_int8_t vec_Snake[w*h]; 373 | Point2D_int8_t P_food = {(int8_t)w/2 + 2, (int8_t)h/2 + 2}; 374 | 375 | vec_Snake[0] = {(int8_t)w/2, (int8_t)h/2}; 376 | 377 | bool won = false; 378 | 379 | while(true) { 380 | 381 | float diff = (millis() - tp); 382 | 383 | float dx = joyStick.x(); 384 | float dy = joyStick.y(); 385 | 386 | if(won) { 387 | dx = 0; 388 | dy = 0; 389 | } 390 | 391 | if(dx*dx + dy*dy > 0) { 392 | if(dx*dx > 0.25) { 393 | if(dx > 0) { 394 | if(dir != 3 && dir != 1) { 395 | dir = 1; 396 | diff = timer; 397 | } 398 | } else { 399 | if(dir != 1 && dir != 3) { 400 | dir = 3; 401 | diff = timer; 402 | } 403 | } 404 | } else if(dy*dy > 0.25) { 405 | if(dy > 0) { 406 | if(dir != 4 && dir != 2) { 407 | dir = 2; 408 | diff = timer; 409 | } 410 | } else { 411 | if(dir != 2 && dir != 4) { 412 | dir = 4; 413 | diff = timer; 414 | } 415 | } 416 | } 417 | } 418 | 419 | if(diff >= timer && !won) { 420 | display.clearDisplay(); 421 | tp = millis(); 422 | 423 | if(vec_Snake[0].x == P_food.x && vec_Snake[0].y == P_food.y) { 424 | snailSize++; 425 | P_food.x = (int8_t)(1 + (w-1)*(float)rand()/RAND_MAX); 426 | P_food.y = (int8_t)(1 + (h-1)*(float)rand()/RAND_MAX); 427 | } 428 | 429 | for(int8_t i = snailSize-1; i > 0; i--) { 430 | if(vec_Snake[i].x == vec_Snake[0].x && vec_Snake[i].y == vec_Snake[0].y) { 431 | won = true; 432 | continue; 433 | } 434 | 435 | vec_Snake[i].x = vec_Snake[i-1].x; 436 | vec_Snake[i].y = vec_Snake[i-1].y; 437 | } 438 | 439 | switch(dir) { 440 | case 1: 441 | vec_Snake[0].y++; 442 | break; 443 | case 2: 444 | vec_Snake[0].x++; 445 | break; 446 | case 3: 447 | vec_Snake[0].y--; 448 | break; 449 | case 4: 450 | vec_Snake[0].x--; 451 | break; 452 | } 453 | 454 | for(int i = 0; i < snailSize; i++) { 455 | if(vec_Snake[i].y < 1) 456 | vec_Snake[i].y = h; 457 | if(vec_Snake[i].y > h) 458 | vec_Snake[i].y = 1; 459 | 460 | if(vec_Snake[i].x < 0) 461 | vec_Snake[i].x = w-1; 462 | if(vec_Snake[i].x > w-1) 463 | vec_Snake[i].x = 0; 464 | display.fillRect(vec_Snake[i].x * cellSize, SCREEN_HEIGHT - vec_Snake[i].y * cellSize, cellSize, cellSize, SSD1306_WHITE); 465 | } 466 | 467 | display.fillRect(P_food.x * cellSize, SCREEN_HEIGHT - P_food.y * cellSize, cellSize, cellSize, SSD1306_WHITE); 468 | 469 | display.fillRect(0, 0, 128, 16, SSD1306_WHITE); 470 | 471 | display.setTextSize(1); 472 | display.setTextColor(SSD1306_BLACK); 473 | display.setCursor(4, 4); 474 | display.print("score: "); 475 | display.print(snailSize); 476 | 477 | display.display(); 478 | } 479 | 480 | if(joyStick.button()) 481 | break; 482 | } 483 | 484 | menu(1); 485 | return; 486 | } 487 | 488 | void drawObstacle(obstacle& obs) { 489 | /* uint16_t x = SCREEN_WIDTH + w/2; 490 | * uint8_t slotSize = 10; 491 | * uint8_t h = 0; 492 | * uint8_t w = 4; 493 | */ 494 | display.fillRect(obs.x - obs.w/2 + 2, 0, obs.w - 4, obs.h, SSD1306_WHITE); 495 | display.fillRect(obs.x - obs.w/2 + 2, obs.h + obs.slotSize, obs.w - 4, SCREEN_HEIGHT - obs.h - obs.slotSize, SSD1306_WHITE); 496 | 497 | display.fillRect(obs.x - obs.w/2, obs.h - 4, obs.w, 4, SSD1306_WHITE); 498 | display.fillRect(obs.x - obs.w/2, obs.h + obs.slotSize, obs.w, 4, SSD1306_WHITE); 499 | } 500 | 501 | void flappyBird(void) { 502 | 503 | uint32_t tp = millis(); 504 | 505 | float o_speed = 0.05; 506 | 507 | float bird_y = 0.5; 508 | float bird_vy = 0; 509 | float g = -1; 510 | 511 | uint8_t birdSize = 3; 512 | 513 | obstacle obs1; 514 | obstacle obs2; 515 | 516 | obs2.x += SCREEN_WIDTH/2; 517 | 518 | int score = 0; 519 | 520 | bool won = false; 521 | 522 | while(true) { 523 | 524 | float dx = joyStick.x(); 525 | float dy = joyStick.y(); 526 | 527 | if(won) { 528 | dx = 0; 529 | dy = 0; 530 | } 531 | 532 | if (dx*dx + dy*dy > 0.5) 533 | { 534 | //jump 535 | bird_vy = 0.5; 536 | } 537 | 538 | float diff = (millis() - tp); 539 | tp = millis(); 540 | 541 | bird_vy += diff * g / 500; 542 | bird_y += diff * bird_vy / 500; 543 | 544 | if(bird_y > 1) { 545 | bird_y = 1; 546 | bird_vy = 0; 547 | } 548 | if(bird_y < 0) { 549 | bird_y = 0; 550 | bird_vy = 0; 551 | } 552 | 553 | if(!won) { 554 | obs1.x -= diff * o_speed; 555 | obs2.x -= diff * o_speed; 556 | } 557 | 558 | if(obs1.x < -obs1.w/2) { 559 | obs1.x = SCREEN_WIDTH + obs1.w/2; 560 | obs1.h = (SCREEN_HEIGHT - obs1.slotSize)*(float)rand()/RAND_MAX; 561 | score++; 562 | } 563 | 564 | if(obs2.x < -obs2.w/2) { 565 | obs2.x = SCREEN_WIDTH + obs2.w/2; 566 | obs2.h = (SCREEN_HEIGHT - obs2.slotSize)*(float)rand()/RAND_MAX; 567 | score++; 568 | } 569 | 570 | if((obs1.x > 30 - LOGO_WIDTH / 2) && (obs1.x < 30 + LOGO_WIDTH / 2)) { 571 | bool collision = (bird_y*SCREEN_HEIGHT - LOGO_HEIGHT / 2 < SCREEN_HEIGHT-obs1.h-obs1.slotSize) || (bird_y*SCREEN_HEIGHT + LOGO_HEIGHT / 2 > SCREEN_HEIGHT-obs1.h); 572 | if(collision) 573 | won = true; 574 | } 575 | 576 | if((obs2.x > 30 - LOGO_WIDTH / 2) && (obs2.x < 30 + LOGO_WIDTH / 2)) { 577 | bool collision = (bird_y*SCREEN_HEIGHT - LOGO_HEIGHT / 2 < SCREEN_HEIGHT-obs2.h-obs2.slotSize) || (bird_y*SCREEN_HEIGHT + LOGO_HEIGHT / 2 > SCREEN_HEIGHT-obs2.h); 578 | if(collision) 579 | won = true; 580 | } 581 | 582 | display.clearDisplay(); 583 | 584 | //display.drawCircle(30, SCREEN_HEIGHT*(1 - bird_y), birdSize, SSD1306_WHITE); 585 | 586 | display.drawBitmap(30 - LOGO_WIDTH / 2, SCREEN_HEIGHT*(1 - bird_y) - LOGO_HEIGHT / 2, logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1); 587 | 588 | display.fillRect(obs1.x - obs1.w/2 + 2, 0, obs1.w - 4, obs1.h, SSD1306_WHITE); 589 | display.fillRect(obs1.x - obs1.w/2 + 2, obs1.h + obs1.slotSize, obs1.w - 4, SCREEN_HEIGHT - obs1.h - obs1.slotSize, SSD1306_WHITE); 590 | display.fillRect(obs1.x - obs1.w/2, obs1.h - 4, obs1.w, 4, SSD1306_WHITE); 591 | display.fillRect(obs1.x - obs1.w/2, obs1.h + obs1.slotSize, obs1.w, 4, SSD1306_WHITE); 592 | 593 | display.fillRect(obs2.x - obs2.w/2 + 2, 0, obs2.w - 4, obs2.h, SSD1306_WHITE); 594 | display.fillRect(obs2.x - obs2.w/2 + 2, obs2.h + obs2.slotSize, obs2.w - 4, SCREEN_HEIGHT - obs2.h - obs1.slotSize, SSD1306_WHITE); 595 | display.fillRect(obs2.x - obs2.w/2, obs2.h - 4, obs2.w, 4, SSD1306_WHITE); 596 | display.fillRect(obs2.x - obs2.w/2, obs2.h + obs2.slotSize, obs2.w, 4, SSD1306_WHITE); 597 | 598 | //drawObstacle(obs1); 599 | //drawObstacle(obs2); 600 | 601 | display.setTextSize(1); 602 | display.setTextColor(SSD1306_WHITE); 603 | display.setCursor(4, 4); 604 | display.print("score: "); 605 | display.print(score); 606 | display.display(); 607 | 608 | if(joyStick.button()) 609 | break; 610 | } 611 | 612 | menu(2); 613 | return; 614 | } 615 | -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vectozavr/GameBoy_arduino/33ee06c2dee2a5f015b1ff765760783a225b90dd/img/1.jpg -------------------------------------------------------------------------------- /img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vectozavr/GameBoy_arduino/33ee06c2dee2a5f015b1ff765760783a225b90dd/img/2.jpg -------------------------------------------------------------------------------- /img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vectozavr/GameBoy_arduino/33ee06c2dee2a5f015b1ff765760783a225b90dd/img/3.jpg -------------------------------------------------------------------------------- /img/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vectozavr/GameBoy_arduino/33ee06c2dee2a5f015b1ff765760783a225b90dd/img/4.jpg -------------------------------------------------------------------------------- /img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vectozavr/GameBoy_arduino/33ee06c2dee2a5f015b1ff765760783a225b90dd/img/5.jpg -------------------------------------------------------------------------------- /img/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vectozavr/GameBoy_arduino/33ee06c2dee2a5f015b1ff765760783a225b90dd/img/6.jpg -------------------------------------------------------------------------------- /img/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vectozavr/GameBoy_arduino/33ee06c2dee2a5f015b1ff765760783a225b90dd/img/7.jpg --------------------------------------------------------------------------------