#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4
#define SCREEN_ADDRESS 0x3C
#define DINO_WIDTH 25
#define DINO_HEIGHT 26
#define DINO_INIT_X 10
#define DINO_INIT_Y 29
#define BASE_LINE_X 0
#define BASE_LINE_Y 54
#define BASE_LINE_X1 127
#define BASE_LINE_Y1 54
#define TREE1_WIDTH 11
#define TREE1_HEIGHT 23
#define TREE2_WIDTH 22
#define TREE2_HEIGHT 23
#define TREE_Y 35
#define JUMP_PIXEL 22 // Number of pixels dino will jump
#define BUTTON_PIN 10 // Pin for the pushbutton
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
static const unsigned char PROGMEM dino1[]={
// 'dino', 25x26px
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x06, 0xff, 0x00, 0x00, 0x0e, 0xff, 0x00,
0x00, 0x0f, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x0f, 0xc0, 0x00,
0x00, 0x0f, 0xfc, 0x00, 0x40, 0x0f, 0xc0, 0x00, 0x40, 0x1f, 0x80, 0x00, 0x40, 0x7f, 0x80, 0x00,
0x60, 0xff, 0xe0, 0x00, 0x71, 0xff, 0xa0, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x7f, 0xff, 0x80, 0x00,
0x7f, 0xff, 0x80, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00,
0x03, 0xfc, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00,
0x01, 0x0c, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00
};
static const unsigned char PROGMEM tree1[]={
// 'tree1', 11x23px
0x1e, 0x00, 0x1f, 0x00, 0x1f, 0x40, 0x1f, 0xe0, 0x1f, 0xe0, 0xdf, 0xe0, 0xff, 0xe0, 0xff, 0xe0,
0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xc0, 0xff, 0x00, 0xff, 0x00, 0x7f, 0x00,
0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00
};
static const unsigned char PROGMEM tree2[]={
// 'tree2', 22x23px
0x1e, 0x01, 0xe0, 0x1f, 0x03, 0xe0, 0x1f, 0x4f, 0xe8, 0x1f, 0xff, 0xfc, 0x1f, 0xff, 0xfc, 0xdf,
0xff, 0xfc, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xfc, 0xff, 0xff,
0xfc, 0xff, 0xef, 0xfc, 0xff, 0x83, 0xfc, 0xff, 0x03, 0xfc, 0xff, 0x03, 0xf8, 0x7f, 0x03, 0xe0,
0x1f, 0x03, 0xe0, 0x1f, 0x03, 0xe0, 0x1f, 0x03, 0xe0, 0x1f, 0x03, 0xe0, 0x1f, 0x03, 0xe0, 0x1f,
0x03, 0xe0, 0x1f, 0x03, 0xe0
};
void setup() {
// Initialize the OLED display
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
for(;;);
}
display.clearDisplay();
// Setup the pushbutton
pinMode(BUTTON_PIN, INPUT_PULLUP); // Use internal pull-up resistor
display.clearDisplay();
introMessage();
while (true) {
if (digitalRead(BUTTON_PIN) == LOW) { // Button pressed
play();
}
}
}
void loop() {
// Main code runs in play() function now
}
void introMessage(){
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 5);
display.println("Dino Game");
display.setTextSize(1);
display.setCursor(5, 45);
display.println("Press Button To Play");
display.display();
}
// Move dino function
void moveDino(int16_t *y, int type = 0){
display.drawBitmap(DINO_INIT_X, *y, dino1, DINO_WIDTH, DINO_HEIGHT, SSD1306_WHITE);
}
// Move tree function
void moveTree(int16_t *x, int type = 0){
if(type == 0){
display.drawBitmap(*x, TREE_Y, tree1, TREE1_WIDTH, TREE1_HEIGHT, SSD1306_WHITE);
}
else if(type == 1){
display.drawBitmap(*x, TREE_Y, tree2, TREE2_WIDTH, TREE2_HEIGHT, SSD1306_WHITE);
}
}
// Game over display with score
void gameOver(int score = 0){
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 5);
display.println("Game Over");
display.setTextSize(1);
display.setCursor(10, 30);
display.print("Score: ");
display.print(score);
display.setCursor(1, 45);
display.println("Press Button To Play Again");
display.display();
}
// Display score while running the game
void displayScore(int score){
display.setTextSize(1);
display.setCursor(64, 10);
display.print("Score: ");
display.print(score);
}
// Main play function
void play(){
int16_t tree_x = 127;
int16_t tree1_x = 195;
int tree_type = random(0, 2);
int tree_type1 = random(0, 2);
int16_t dino_y = DINO_INIT_Y;
int jump = 0;
int score = 0;
// Speed factors
int treeSpeed = 3; // Higher value = faster tree movement
int dinoJumpSpeed = 2; // Higher value = faster jump speed
for(;;){
display.clearDisplay();
// Read the button press for jump
if (digitalRead(BUTTON_PIN) == LOW) {
if (jump == 0) {
jump = 1; // Start jumping
}
}
// Dino jump logic
if(jump == 1){
dino_y -= dinoJumpSpeed; // Increase jump speed here
if(dino_y == (DINO_INIT_Y - JUMP_PIXEL)){
jump = 2;
score++;
}
}
else if(jump == 2){
dino_y += dinoJumpSpeed; // Increase fall speed here
if(dino_y == DINO_INIT_Y){
jump = 0;
}
}
// Check for collision with trees
if ((tree_x <= (DINO_INIT_X + DINO_WIDTH) && tree_x >= (DINO_INIT_X + (DINO_WIDTH / 2))) ||
(tree1_x <= (DINO_INIT_X + DINO_WIDTH) && tree1_x >= (DINO_INIT_X + (DINO_WIDTH / 2)))) {
if(dino_y >= (DINO_INIT_Y - 3)){
gameOver(score);
return; // End game and show game over screen
}
}
displayScore(score);
moveTree(&tree_x, tree_type);
moveTree(&tree1_x, tree_type1);
moveDino(&dino_y);
display.drawLine(0, 54, 127, 54, SSD1306_WHITE);
// Increase tree speed by decrementing more per frame
tree_x -= treeSpeed;
tree1_x -= treeSpeed;
if(tree_x == 0) {
tree_x = 127;
tree_type = random(0, 2);
}
if(tree1_x == 0) {
tree1_x = 195;
tree_type1 = random(0, 2);
}
display.display();
}
}