This is a detailed description of Project 2. It covers the purpose of the project, the materials used, and the results achieved. The project involves various components and techniques to achieve its goals.
More detailed information about the project goes here. This can include technical specifications, step-by-step guides, or additional resources for those interested in replicating or learning more about the project.
Note: to add all necessary libraries for them see the video
//THIS CODE WAS WRITTEN BY @ ROBOTICS BY ARNAV ORIGINAL: ( ARNAV BHATNAGAR ) FOR A YOUTUBE VIDEO (how to make a gaming console at home) FOR oled display // ON 5-05-2024 PLEASE CONSIDER SUBSCRIBING ROBOTICS BY ARNAV ON YOUTUBE :) AND FOLLOW ON INSTA (ARNAV BHATNAGAR4) :) #include <SPI> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // Initialise the display #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // pin the flap button is attached to #define FLAP_BUTTON 2 // Initialise 'sprites' #define SPRITE_HEIGHT 16 #define SPRITE_WIDTH 16 // Two frames of animation static const unsigned char PROGMEM wing_down_bmp[] = { B00000000, B00000000, B00000000, B00000000, B00000011, B11000000, B00011111, B11110000, B00111111, B00111000, B01111111, B11111110, B11111111, B11000001, B11011111, B01111110, B11011111, B01111000, B11011111, B01111000, B11001110, B01111000, B11110001, B11110000, B01111111, B11100000, B00111111, B11000000, B00000111, B00000000, B00000000, B00000000, }; static const unsigned char PROGMEM wing_up_bmp[] = { B00000000, B00000000, B00000000, B00000000, B00000011, B11000000, B00011111, B11110000, B00111111, B00111000, B01110001, B11111110, B11101110, B11000001, B11011111, B01111110, B11011111, B01111000, B11111111, B11111000, B11111111, B11111000, B11111111, B11110000, B01111111, B11100000, B00111111, B11000000, B00000111, B00000000, B00000000, B00000000, }; // Game variables #define GAME_SPEED 50 int game_state = 1; // 0 = game over screen, 1 = in game int score = 0; // current game score int high_score = 0; // highest score since the nano was reset int bird_x = (int)display.width() / 4; // birds x position (along) - initialised to 1/4 the way along the screen int bird_y; // birds y position (down) int momentum = 0; // how much force is pulling the bird down int wall_x[2]; // an array to hold the walls x positions int wall_y[2]; // an array to hold the walls y positions int wall_gap = 30; // size of the wall wall_gap in pixels int wall_width = 10; // width of the wall in pixels void setup() { // used for debugging output Serial.begin(9600); // initialise the display // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64 Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } display.setTextColor(WHITE); display.clearDisplay(); // Setup the flap button pin for input // We use INPUT_PULLUP so we don't need a resitor on the switch pinMode(FLAP_BUTTON, INPUT_PULLUP); // Initialise the random number generator randomSeed(analogRead(0)); } void loop() { if (game_state == 0) { // in game display.clearDisplay(); // If the flap button is currently pressed, reduce the downward force on the bird a bit. // Once this foce goes negative the bird goes up, otherwise it falls towards the ground // gaining speed if (digitalRead(FLAP_BUTTON) == LOW) { momentum = -4; } // increase the downward force on the bird momentum += 1; // add the downward force to the bird position to determine it's new position bird_y += momentum; // make sure the bird doesn't fly off the top of the screen if (bird_y < 0 ) { bird_y = 0; } // make sure the bird doesn't fall off the bottom of the screen // give it a slight positive lift so it 'waddles' along the ground. if (bird_y > display.height() - SPRITE_HEIGHT) { bird_y = display.height() - SPRITE_HEIGHT; momentum = -2; } // display the bird // if the momentum on the bird is negative the bird is going up! if (momentum < 0) { // display the bird using a randomly picked flap animation frame if (random(2) == 0) { display.drawBitmap(bird_x, bird_y, wing_down_bmp, 16, 16, WHITE); } else { display.drawBitmap(bird_x, bird_y, wing_up_bmp, 16, 16, WHITE); } } else { // bird is currently falling, use wing up frame display.drawBitmap(bird_x, bird_y, wing_up_bmp, 16, 16, WHITE); } // now we draw the walls and see if the player has hit anything for (int i = 0 ; i < 2; i++) { // draw the top half of the wall display.fillRect(wall_x[i], 0, wall_width, wall_y[i], WHITE); // draw the bottom half of the wall display.fillRect(wall_x[i], wall_y[i] + wall_gap, wall_width, display.height() - wall_y[i] + wall_gap, WHITE); // if the wall has hit the edge of the screen // reset it back to the other side with a new gap position if (wall_x[i] < 0) { wall_y[i] = random(0, display.height() - wall_gap); wall_x[i] = display.width(); } // if the bird has passed the wall, update the score if (wall_x[i] == bird_x) { score++; // highscore is whichever is bigger, the current high score or the current score high_score = max(score, high_score); } // if the bird is level with the wall and not level with the gap - game over! if ( (bird_x + SPRITE_WIDTH > wall_x[i] && bird_x < wall_x[i] + wall_width) // level with wall && (bird_y < wall_y[i] || bird_y + SPRITE_HEIGHT > wall_y[i] + wall_gap) // not level with the gap ) { // display the crash and pause 1/2 a second display.display(); delay(500); // switch to game over state game_state = 1; } // move the wall left 4 pixels wall_x[i] -= 4; } // display the current score boldTextAtCenter(0, (String)score); // now display everything to the user and wait a bit to keep things playable display.display(); delay(GAME_SPEED); } else { // game over screen screenWipe(10); outlineTextAtCenter(1, "flaffy BIRD by arnav"); outlineTextAtCenter(2, "subscriberoboticsbyarnav"); textAtCenter(display.height() / 2 - 8, "GAME OVER"); textAtCenter(display.height() / 2, String(score)); boldTextAtCenter(display.height() - 16, "HIGH SCORE"); boldTextAtCenter(display.height() - 8, String(high_score)); display.display(); // wait while the user stops pressing the button while (digitalRead(FLAP_BUTTON) == LOW); // setup a new game bird_y = display.height() / 2; momentum = -4; wall_x[0] = display.width() ; wall_y[0] = display.height() / 2 - wall_gap / 2; wall_x[1] = display.width() + display.width() / 2; wall_y[1] = display.height() / 2 - wall_gap / 1; score = 0; // wait until the user presses the button while (digitalRead(FLAP_BUTTON) == HIGH); // start a new game screenWipe(10); game_state = 0; } } /** * clear the screen using a wipe down animation */ void screenWipe(int speed) { // progressivly fill screen with white for (int i = 0; i < display.height(); i += speed) { display.fillRect(0, i, display.width(), speed, WHITE); display.display(); } // progressively fill the screen with black for (int i = 0; i < display.height(); i += speed) { display.fillRect(0, i, display.width(), speed, BLACK); display.display(); } } /** * displays txt at x,y coordinates */ void textAt(int x, int y, String txt) { display.setCursor(x, y); display.print(txt); } /** * displays text centered on the line */ void textAtCenter(int y, String txt) { textAt(display.width() / 2 - txt.length() * 3, y, txt); } /** * displays outlined text centered on the line */ void outlineTextAtCenter(int y, String txt) { int x = display.width() / 2 - txt.length() * 3; display.setTextColor(WHITE); textAt(x - 1, y, txt); textAt(x + 1, y, txt); textAt(x, y - 1, txt); textAt(x, y + 1, txt); display.setTextColor(BLACK); textAt(x, y, txt); display.setTextColor(WHITE); } /** * displays bold text centered on the line */ void boldTextAtCenter(int y, String txt) { int x = display.width() / 2 - txt.length() * 3; textAt(x, y, txt); textAt(x + 1, y, txt); }