#include <Wire.h>
#include "values.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define JUMP_BUTTON_PIN 2
#define DINO_WIDTH 30
#define DINO_HEIGHT 32
#define CACTUS_WIDTH 24
#define CACTUS_HEIGHT 24
int dinoX = 10;
int dinoY = SCREEN_HEIGHT - DINO_HEIGHT;
bool isJumping = false;
int jumpVelocity = 0;
const int baseGravity = 1; // Base gravity value
int cactusCount = 1;
int obstacleX[3] = {SCREEN_WIDTH + 10, SCREEN_WIDTH + 50, SCREEN_WIDTH + 100};
int obstacleY = SCREEN_HEIGHT - CACTUS_HEIGHT;
int speed = 2;
int score = 0;
unsigned long previousMillis = 0;
const long interval = 32; // Approximately 30 FPS
void setup() {
Serial.begin(115200);
if(!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
oled.clearDisplay();
oled.display();
oled.setTextColor(WHITE);
oled.setTextSize(1);
pinMode(JUMP_BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
delay(10);
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Save previous positions for partial update
static int prevDinoY = dinoY;
static int prevObstacleX[3] = {obstacleX[0], obstacleX[1], obstacleX[2]};
// Handle dino jumping
if (isJumping) {
dinoY -= jumpVelocity;
jumpVelocity -= (baseGravity +speed/10);
if (dinoY >= SCREEN_HEIGHT - DINO_HEIGHT) {
dinoY = SCREEN_HEIGHT - DINO_HEIGHT;
isJumping = false;
}
}
// Move the obstacles
for (int i = 0; i < cactusCount; i++) {
obstacleX[i] -= speed;
if (obstacleX[i] < 0) {
obstacleX[i] = SCREEN_WIDTH;
}
// Collision detection
if (dinoX + DINO_WIDTH > obstacleX[i] && dinoX < obstacleX[i] + CACTUS_WIDTH && dinoY + DINO_HEIGHT > obstacleY && dinoY < obstacleY + CACTUS_HEIGHT) {
Serial.println("Collision detected. Displaying game over screen...");
// Display game over screen
oled.clearDisplay();
oled.setCursor(0, 20);
oled.println("Game Over!\n Score:");
oled.println(score);
oled.display();
delay(2000);
// Reset game
obstacleX[i] = SCREEN_WIDTH;
dinoY = SCREEN_HEIGHT - DINO_HEIGHT;
isJumping = false;
score = 0;
speed = 4;
}
}
// Increase score after every frame
score++;
// Clear display for partial update
oled.clearDisplay();
// Draw the dino
oled.drawBitmap(dinoX, dinoY, dinoBitmap, DINO_WIDTH, DINO_HEIGHT, SSD1306_WHITE);
// Draw the obstacles
for (int i = 0; i < cactusCount; i++) {
oled.drawBitmap(obstacleX[i], obstacleY, cactusBitmap, CACTUS_WIDTH, CACTUS_HEIGHT, SSD1306_WHITE);
}
// Display the updated frame
oled.display();
// Update previous positions
prevDinoY = dinoY;
for (int i = 0; i < cactusCount; i++) {
prevObstacleX[i] = obstacleX[i];
}
}
// Handle user input (jumping)
if (digitalRead(JUMP_BUTTON_PIN) == LOW && !isJumping) {
isJumping = true;
jumpVelocity = 10;
}
}