Flappy Bird na arduino

Typ_projektu
Arduino
Zdjecie główne
Krótki opis projektu

Flappy Bird na arduino!!!

Założenia projektu:

Stworzenie prostej gry zaprogramowanej w arduino IED. Gra ma wykorzystywać maksymalnie 6 przycisków ale przede wszystkim ma być przyjemna dla oka i w rozgrywce. 

Niezbędne elementy

Użyte części: 

-arduino uno

-wyświetlacz OLED 16x16 z czterema wyjściowymi pinami

-płytka pcb z zamontowanymi 6-cioma guzikami i czterema wejściami na piny

główne narzędzia jakie wykorzystywaliśmy to chat gpt i nasze szare komórki. 

Opis projektu

Projekt został użyty przy pomocy narzędzia AI-  chatGPT - na początku został poproszony o  stworzenie najprostrzej wersji gry, następnie, z jego użyciem, naprawiono usterki i dodawano ulepszenia.

Kod został podzielony na oddzielne funkcje dodające konkretne elementy poruszanie się w nim i drobne modyfikacje były relatywnie proste. 

Najcięższe było znalezienie ustawienie losowo generowanych się przeszkód oraz znalezienie idealnej prędkości lotu/opadania ptaka. 

Ostatnimi modyfikacjami jakie zostały zrobione - było dodanie napisu "Game over" i podawaną ilość pokonanych przeszkód jako "score:".

Zdjęcia
kod programu
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define BIRD_SIZE 6
#define GRAVITY 0.2
#define JUMP_FORCE -2
#define PIPE_WIDTH 20
#define PIPE_GAP 24 // Stała przerwa między rurami
#define PIPE_SPEED 2
#define PIPE_DISTANCE 60
#define MIN_PIPE_GAP_TOP 5 // Minimalna odległość od góry
#define MIN_PIPE_GAP_BOTTOM 5 // Minimalna odległość od dołu

int birdX = SCREEN_WIDTH / 4;
float birdY = SCREEN_HEIGHT / 2;
float birdVelocityY = 0;
int pipeX[3];
int pipeGapY[3];
int score = 0;

void setup() {
  Serial.begin(9600);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();
  pinMode(4, INPUT_PULLUP);

  // Generowanie losowej wysokości dla wszystkich rur na początku gry
  for (int i = 0; i < 3; i++) {
    pipeX[i] = SCREEN_WIDTH + i * PIPE_DISTANCE;
    int upperGap = random(MIN_PIPE_GAP_TOP, SCREEN_HEIGHT - PIPE_GAP - MIN_PIPE_GAP_BOTTOM); // Losowa wysokość dla górnej części otworu
    pipeGapY[i] = upperGap;
  }
}

void loop() {
  handleInput();
  updateBird();
  updatePipes();
  
  display.clearDisplay();
  drawBird();
  for (int i = 0; i < 3; i++) {
    drawPipes(i);
  }
  drawScore();
  display.display();
  
  if (checkCollision()) {
    displayGameOver();
    resetGame();
  }
  
  delay(20);
}

void handleInput() {
  if (digitalRead(4) == LOW) {
    birdVelocityY = JUMP_FORCE;
  }
}

void updateBird() {
  birdVelocityY += GRAVITY;
  birdY += birdVelocityY;
  birdY = max(min(birdY, (float)SCREEN_HEIGHT - BIRD_SIZE), 0.0f);
}

void updatePipes() {
  for (int i = 0; i < 3; i++) {
    pipeX[i] -= PIPE_SPEED;
    if (pipeX[i] < -PIPE_WIDTH) {
      pipeX[i] += 3 * PIPE_DISTANCE;
      int upperGap = random(MIN_PIPE_GAP_TOP, SCREEN_HEIGHT - PIPE_GAP - MIN_PIPE_GAP_BOTTOM); // Losowa wysokość dla górnej części otworu
      pipeGapY[i] = upperGap;
      score++;
    }
  }
}

bool checkCollision() {
  for (int i = 0; i < 3; i++) {
    if (birdX + BIRD_SIZE > pipeX[i] && birdX < pipeX[i] + PIPE_WIDTH) {
      if (birdY < pipeGapY[i] || birdY + BIRD_SIZE > pipeGapY[i] + PIPE_GAP) {
        return true;
      }
    }
  }
  if (birdY <= 0 || birdY >= SCREEN_HEIGHT - BIRD_SIZE) {
    return true;
  }
  return false;
}

void drawBird() {
  display.fillRect(birdX, birdY, BIRD_SIZE, BIRD_SIZE, SSD1306_WHITE);
  
}

void drawPipes(int i) {
  display.fillRect(pipeX[i], 0, PIPE_WIDTH, pipeGapY[i], SSD1306_WHITE);
  display.fillRect(pipeX[i], pipeGapY[i] + PIPE_GAP, PIPE_WIDTH, SCREEN_HEIGHT - pipeGapY[i] - PIPE_GAP, SSD1306_WHITE);
}

void drawScore() {
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.print("Score: ");
  display.println(score);
}

void displayGameOver() {
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor((SCREEN_WIDTH - 6 * 12)/2, SCREEN_HEIGHT / 2 - 16); // Dostosowanie pozycji dla dwóch linii
  display.println("GAME");
  display.setCursor((SCREEN_WIDTH - 6 * 12)/2, SCREEN_HEIGHT / 2); // Nowa linia dla "OVER"
  display.println("OVER");
  
  int scoreX = (SCREEN_WIDTH - 6 * 12) / 2; // Ustawienie pozycji X na środek ekranu
  int scoreY = (SCREEN_HEIGHT / 2) + 16; // Położenie poniżej "GAME OVER"

  // Ustawienie kursora dla wyniku
  display.setCursor(scoreX, scoreY);
  drawScore();
  display.display();
  
  delay(1000);
}

void resetGame() {
  birdY = SCREEN_HEIGHT / 2;
  birdVelocityY = 0;
  score = 0;
  // Resetujemy rury przy restarcie gry
  for (int i = 0; i < 3; i++) {
    pipeX[i] = SCREEN_WIDTH + i * PIPE_DISTANCE;
    int upperGap = random(MIN_PIPE_GAP_TOP, SCREEN_HEIGHT - PIPE_GAP - MIN_PIPE_GAP_BOTTOM); // Losowa wysokość dla górnej części otworu
    pipeGapY[i] = upperGap;
  }
  delay(1000); // Krótka pauza przed restartem gry
}
Youtube
Tagi
arduino gra OLED FLAPPY BIRD