#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define JUMP_BUTTON 2
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// 🦖 **Dino (16x16 pixels)**
const unsigned char dinoBitmap[] PROGMEM = {
0b00000011, 0b00000000,
0b00000111, 0b00000000,
0b00001111, 0b00000000,
0b00001111, 0b00000000,
0b00011111, 0b00000000,
0b00011111, 0b10000000,
0b00011111, 0b11000000,
0b00001111, 0b11000000,
0b00001111, 0b11000000,
0b00001111, 0b10000000,
0b00001101, 0b10000000,
0b00000001, 0b00000000,
0b00000010, 0b00000000,
0b00000010, 0b00000000,
0b00000010, 0b00000000,
0b00000110, 0b00000000
};
// 🌵 **Cactus (8x12 pixels)**
const unsigned char cactusBitmap[] PROGMEM = {
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00111100,
0b00111100,
0b00111100,
0b00111100
};
// **Game Variables**
int dinoX = 10;
int dinoY = 40;
bool isJumping = false;
bool goingUp = true;
int jumpHeight = 18;
int groundLevel = 40;
int obstacleX = SCREEN_WIDTH;
bool gameOver = false;
// **Button Debounce Variables**
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void setup() {
pinMode(JUMP_BUTTON, INPUT_PULLUP); // Enable internal pull-up resistor
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for (;;);
}
display.clearDisplay();
}
void loop() {
if (gameOver) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(30, 30);
display.print("GAME OVER!");
display.display();
return;
}
// **Read Button with Debounce**
if (millis() - lastDebounceTime > debounceDelay) {
if (digitalRead(JUMP_BUTTON) == LOW && !isJumping) {
isJumping = true;
goingUp = true;
lastDebounceTime = millis(); // Reset debounce timer
}
}
// **Jump Mechanics**
if (isJumping) {
if (goingUp) {
dinoY -= 3;
if (dinoY <= (groundLevel - jumpHeight)) {
goingUp = false;
}
} else {
dinoY += 3;
if (dinoY >= groundLevel) {
dinoY = groundLevel;
isJumping = false;
}
}
}
// **Move Obstacle**
obstacleX -= 3;
if (obstacleX < -10) {
obstacleX = SCREEN_WIDTH + random(20, 50); // Randomize new position
}
// **Check Collision**
if (obstacleX < dinoX + 12 && obstacleX + 8 > dinoX && dinoY + 12 >= groundLevel) {
gameOver = true;
}
// **Draw Everything**
display.clearDisplay();
display.drawLine(0, groundLevel + 12, SCREEN_WIDTH, groundLevel + 12, SSD1306_WHITE);
display.drawBitmap(dinoX, dinoY, dinoBitmap, 16, 16, SSD1306_WHITE);
display.drawBitmap(obstacleX, groundLevel, cactusBitmap, 8, 12, SSD1306_WHITE);
display.display();
delay(50);
}