#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD setup (0x27 or 0x3F depending on your LCD)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Game elements
#define DINO 'D'
#define CACTUS '#'
#define GROUND '_'
// Pins
const int JOY_Y = A0; // Joystick Y axis
const int BUTTON = 8; // Start button
const int BUZZER = 3; // Buzzer
// Game variables
int dinoPos = 1; // 0=up, 1=down
int cactusPos = 15; // Cactus position
int score = 0; // Player score
bool gameRunning = false; // Game state
void setup() {
// Initialize components
lcd.init();
lcd.backlight();
pinMode(BUTTON, INPUT_PULLUP);
// Welcome screen
lcd.setCursor(0, 0);
lcd.print("Press button");
lcd.setCursor(0, 1);
lcd.print("to start!");
}
void loop() {
// Start game when button pressed
if (!gameRunning && digitalRead(BUTTON) == LOW) {
startGame();
}
// Main game loop
if (gameRunning) {
playGame();
delay(200); // Game speed
}
}
void startGame() {
gameRunning = true;
score = 0;
dinoPos = 1;
cactusPos = 15;
lcd.clear();
beep(100);
}
void playGame() {
// Jump when joystick moved up
if (analogRead(JOY_Y) < 400) {
dinoPos = 0;
} else {
dinoPos = 1;
}
// Draw game screen
lcd.clear();
// Draw ground line
for (int i = 0; i < 16; i++) {
lcd.setCursor(i, 1);
lcd.print(GROUND);
}
// Draw dino
lcd.setCursor(1, dinoPos);
lcd.print(DINO);
// Draw cactus
lcd.setCursor(cactusPos, 1);
lcd.print(CACTUS);
// Draw score
lcd.setCursor(12, 0);
lcd.print(score);
// Check collision
if (cactusPos == 1 && dinoPos == 1) {
gameOver();
return;
}
// Move cactus
cactusPos--;
// Reset cactus and increase score
if (cactusPos < 0) {
cactusPos = 15;
score++;
beep(50);
}
}
void gameOver() {
gameRunning = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Game Over!");
lcd.setCursor(0, 1);
lcd.print("Score: ");
lcd.print(score);
beep(300);
delay(2000);
// Return to start screen
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press button");
lcd.setCursor(0, 1);
lcd.print("to restart");
}
void beep(int duration) {
tone(BUZZER, 1000, duration);
}