#include // Library for the OLED display #define BUTTON_PIN 3 // Pin connected to the jump button // OLED display initialization Adafruit_SH1106G display = Adafruit_SH1106G(128, 64, &Wire, -1); // Game variables bool isJumping = false; // Tracks whether the dino is in the air bool gameOver = false; // Game over flag int dinoY = 40; // Dino's vertical position int velocity = 0; // Dino's vertical velocity const int gravity = 2; // Gravity effect on the jump const int groundY = 40; // Y position of the ground // Cactus obstacle positions int cactusX1 = 128; // First cactus starting position int cactusX2 = 180; // Second cactus starting position int gameSpeed = 3; // Speed at which obstacles move // Timing and score variables float lastSpeedIncrease = 0; // Stores the last time speed was increased float score = 0; // Player's score // Button press tracking bool buttonPressed = false; void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); // Set button pin as input with pull-up resistor display.begin(0x3C); // Initialize display with I2C address randomSeed(analogRead(0)); // Makes a different set of random numbers every time the code runs } void loop() { int buttonState = digitalRead(BUTTON_PIN); // Read button state // Handle game over state if (gameOver) { if (buttonState == HIGH && !buttonPressed) { // Detect button press for restart buttonPressed = true; } if (buttonState == LOW && buttonPressed) { // When button is released, reset game buttonPressed = false; resetGame(); } return; } // Handle jump mechanics if (buttonState == LOW && !buttonPressed && dinoY == groundY) { buttonPressed = true; isJumping = true; velocity = -13; } if (buttonState == HIGH) { buttonPressed = false; } // Update dino's vertical position based on velocity and gravity if (isJumping) { dinoY += velocity; velocity += gravity; // Apply gravity effect if (dinoY >= groundY) { // Stop jumping when reaching the ground dinoY = groundY; isJumping = false; } } // Move cacti to the left cactusX1 -= gameSpeed; cactusX2 -= gameSpeed; // Reset cactus position when it moves off screen if (cactusX1 < -10) { cactusX1 = 128 + random(0, 40); } // Ensure second cactus resets properly if (cactusX2 < -10) { cactusX2 = cactusX1 + random(30, 60); // Place it correctly relative to the first cactus } // Increase game speed over time if (millis() - lastSpeedIncrease > 3000) { gameSpeed++; lastSpeedIncrease = millis(); } // Increase player score by 1 score++; // Update display display.clearDisplay(); display.fillRect(10, dinoY, 10, 10, SH110X_WHITE); // Draw dino display.fillRect(cactusX1, groundY, 10, 15, SH110X_WHITE); // Draw first cactus display.fillRect(cactusX2, groundY, 10, 15, SH110X_WHITE); // Draw second cactus display.drawLine(0, 58, 128, 58, SH110X_WHITE); // Draw ground display.setTextSize(1); display.setTextColor(SH110X_WHITE); display.setCursor(0, 0); display.print("Score: "); display.print(score / 10); // Display score display.display(); // Collision detection bool hitCactus1 = (cactusX1 < 20 && cactusX1 > 5 && dinoY == groundY); bool hitCactus2 = (cactusX2 < 20 && cactusX2 > 5 && dinoY == groundY); // If collision detection occurs, trigger game over if (hitCactus1 || hitCactus2) { gameOver = true; display.clearDisplay(); display.setCursor(10, 5); display.print("Final Score: "); display.print(score / 10); display.setTextSize(2); display.setCursor(10, 20); display.print("Game Over"); display.setTextSize(1); display.setCursor(10, 45); display.print("Press to restart"); display.display(); } } void resetGame() { // Reset game variables isJumping = false; dinoY = groundY; velocity = 0; cactusX1 = 128; cactusX2 = 180; gameSpeed = 3; score = 0; gameOver = false; lastSpeedIncrease = millis(); // Clear and refresh display display.clearDisplay(); display.display(); }