#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BUTTON_PIN 2
// Bird variables
int birdY;
int birdVelocity;
const int gravity = 1;
// Pipe variables
int pipeX;
int pipeGap;
int pipeWidth;
int pipeHeight;
const int pipeSpeed = 2;
// Game variables
bool gameRunning;
int score;
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // Initialize with I2C address 0x3C
pinMode(BUTTON_PIN, INPUT_PULLUP);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.display();
resetGame();
}
void loop() {
if (gameRunning) {
handleInput();
updateBird();
updatePipes();
checkCollisions();
drawGame();
} else {
if (digitalRead(BUTTON_PIN) == LOW) {
resetGame();
}
}
}
void handleInput() {
if (digitalRead(BUTTON_PIN) == LOW) {
birdVelocity -= 4;
}
}
void updateBird() {
birdVelocity += gravity;
birdY += birdVelocity;
if (birdY <= 0) {
birdY = 0;
birdVelocity = 0;
}
if (birdY >= SCREEN_HEIGHT - 1) {
birdY = SCREEN_HEIGHT - 1;
gameRunning = false;
}
}
void updatePipes() {
pipeX -= pipeSpeed;
if (pipeX + pipeWidth <= 0) {
pipeX = SCREEN_WIDTH;
pipeGap = random(10, SCREEN_HEIGHT - 20);
score++;
}
}
void checkCollisions() {
// Check collision with pipes
if (birdY <= pipeGap || birdY >= pipeGap + 20) {
if (pipeX <= 12 && pipeX + pipeWidth >= 4) {
gameRunning = false;
}
}
}
void drawGame() {
display.clearDisplay();
// Draw bird
display.drawCircle(12, birdY, 4, WHITE);
// Draw pipes
display.drawRect(pipeX, 0, pipeWidth, pipeGap, WHITE);
display.drawRect(pipeX, pipeGap + 20, pipeWidth, SCREEN_HEIGHT - pipeGap - 20, WHITE);
// Draw score
display.setCursor(SCREEN_WIDTH / 2 - 3, 0);
display.print(score);
display.display();
}
void resetGame() {
gameRunning = true;
birdY = SCREEN_HEIGHT / 2;
birdVelocity = 0;
pipeX = SCREEN_WIDTH;
pipeGap = random(10, SCREEN_HEIGHT - 20);
pipeWidth = 16;
pipeHeight = 20;
score = 0;
}