Project 2 Details

Projects Home SUBSCRIBE

Project 2: Example Project

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.

Circuit Diagram

Project 2 Circuit Diagram

Project Details

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.

Arduino Code

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);
                        
                        }