#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
// Button Pins
#define BUTTON_LEFT D10 // Move Left
#define BUTTON_RIGHT D9 // Move Right
#define BUTTON_JUMP D8 // Jump
// Game Constants
#define DINO_WIDTH 16
#define DINO_HEIGHT 16
#define GROUND_Y 50
#define GRAVITY 1
#define JUMP_HEIGHT 10
#define OBSTACLE_WIDTH 10
#define OBSTACLE_HEIGHT 16
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int dinoX = 10;
int dinoY = GROUND_Y - DINO_HEIGHT;
int dinoVelY = 0;
bool isJumping = false;
int score = 0;
int obstacleX = SCREEN_WIDTH;
int obstacleY = GROUND_Y - OBSTACLE_HEIGHT;
int obstacleSpeed = 1;
void setup() {
Serial.begin(115200);
// Initialize OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
// Set button pins as input with pull-up resistors
pinMode(BUTTON_LEFT, INPUT_PULLUP);
pinMode(BUTTON_RIGHT, INPUT_PULLUP);
pinMode(BUTTON_JUMP, INPUT_PULLUP);
}
void loop() {
display.clearDisplay();
// Handle input for movement and jumping
if (digitalRead(BUTTON_LEFT) == LOW && dinoX > 0) {
dinoX -= 2; // Move left
}
if (digitalRead(BUTTON_RIGHT) == LOW && dinoX < SCREEN_WIDTH - DINO_WIDTH) {
dinoX += 2; // Move right
}
// Jumping logic
if (digitalRead(BUTTON_JUMP) == LOW && !isJumping) {
dinoVelY = -JUMP_HEIGHT; // Jump up
isJumping = true;
}
// Apply gravity
if (isJumping) {
dinoVelY += GRAVITY; // Increase downward velocity
dinoY += dinoVelY; // Move the dino down
if (dinoY >= GROUND_Y - DINO_HEIGHT) {
dinoY = GROUND_Y - DINO_HEIGHT; // Land on the ground
isJumping = false; // Reset jumping state
}
}
// Move obstacle
obstacleX -= obstacleSpeed;
if (obstacleX < 0) {
obstacleX = SCREEN_WIDTH; // Reset obstacle to the right
score++; // Increase score as obstacle crosses
}
// Check for collision with the obstacle
if (dinoX + DINO_WIDTH > obstacleX && dinoX < obstacleX + OBSTACLE_WIDTH &&
dinoY + DINO_HEIGHT > obstacleY) {
// Collision detected, reset game
gameOver();
}
// Draw game elements
drawDino();
drawObstacle();
drawGround();
displayScore();
display.display();
delay(30); // Control frame rate
}
void drawDino() {
display.fillRect(dinoX, dinoY, DINO_WIDTH, DINO_HEIGHT, SSD1306_WHITE);
}
void drawObstacle() {
display.fillRect(obstacleX, obstacleY, OBSTACLE_WIDTH, OBSTACLE_HEIGHT, SSD1306_WHITE);
}
void drawGround() {
display.drawLine(0, GROUND_Y, SCREEN_WIDTH, GROUND_Y, SSD1306_WHITE);
}
void displayScore() {
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(5, 5);
display.print("Score: ");
display.print(score);
}
void gameOver() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(SCREEN_WIDTH / 4, SCREEN_HEIGHT / 3);
display.print("Game Over");
display.setTextSize(1);
display.setCursor(SCREEN_WIDTH / 4, SCREEN_HEIGHT / 2);
display.print("Score: ");
display.print(score);
display.display();
delay(2000); // Wait for 2 seconds before restarting
resetGame();
}
void resetGame() {
dinoX = 10;
dinoY = GROUND_Y - DINO_HEIGHT;
dinoVelY = 0;
isJumping = false;
score = 0;
obstacleX = SCREEN_WIDTH;
obstacleSpeed = 1;
}