#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//These lines include the necessary libraries for working with the Adafruit SSD1306 OLED display.
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
//Defines the screen width and height.
#define OLED_RESET 4
#define SCREEN_ADDRESS 0x3C
//Defines the reset pin for the OLED display and the I2C address of the display.
#define DINO_WIDTH 25
#define DINO_HEIGHT 26
#define DINO_INIT_X 10
#define DINO_INIT_Y 29
//Defines the width, height, initial X and Y coordinates of the dinosaur character.
#define BASE_LINE_X 0
#define BASE_LINE_Y 54
#define BASE_LINE_X1 127
#define BASE_LINE_Y1 54
//Defines the base line coordinates for the game.
#define TREE1_WIDTH 11
#define TREE1_HEIGHT 23
#define TREE2_WIDTH 22
#define TREE2_HEIGHT 23
#define TREE_Y 35
//Defines the width, height, and Y coordinate of the trees.
#define JUMP_PIXEL 22
#define BUTTON_PIN_START 2
#define BUTTON_PIN_JUMP 3
//Defines the pixel value for the dinosaur jump, and the pin numbers for the start and jump buttons.
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
};
int jump = 0;
int16_t dino_y = DINO_INIT_Y;
int score = 0;
//Initializes variables for jump state, dinosaur Y coordinate, and score.
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN_START, INPUT_PULLUP);
pinMode(BUTTON_PIN_JUMP, INPUT_PULLUP);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
introMessage();
}
//Setup function that initializes serial communication, button pins, OLED display, and calls the introMessage function.
//while(true) == for(;;)
void loop() {
if (digitalRead(BUTTON_PIN_START) == LOW) {
play();
}
if (digitalRead(BUTTON_PIN_JUMP) == LOW) {
if(jump==0) jump=1;
}
if(jump==1){
dino_y--;
if(dino_y== (DINO_INIT_Y-JUMP_PIXEL)){
jump=2;
score++;
}
}
else if(jump==2){
dino_y++;
if(dino_y== DINO_INIT_Y){
jump=0;
}
}
}
//Main loop function that checks for button presses to start the game or make the dinosaur jump
void introMessage(){
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10,5);
display.println("Dino Game");
display.setTextSize(1);
display.setCursor(5,35);
display.println("Press Red to Start");
display.setTextSize(1);
display.setCursor(5,45);
display.println("Press Blue to Jump");
display.display();
}
//Function to display the intro message on the OLED display.
void moveDino(int16_t *y, int type=0){
display.drawBitmap(DINO_INIT_X, *y, dino1, DINO_WIDTH, DINO_HEIGHT, SSD1306_WHITE);
}
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);
}
}
//Functions to move the dinosaur and trees on the screen
// *y is the value pointed to by the pointer y
//if y points the value 42, then *y would be to `42`
//This means that y stores the memory address of a 16-bit integer variable
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 Red to Play Again");
display.display();
}
void displayScore(int score){
display.setTextSize(1);
display.setCursor(64,10);
display.print("Score: ");
display.print(score);
}
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;
for(;;){
display.clearDisplay();
if (digitalRead(BUTTON_PIN_JUMP) == LOW){
if(jump==0) jump=1;
}
if(jump==1){
dino_y--;
if(dino_y== (DINO_INIT_Y-JUMP_PIXEL)){
jump=2;
score++;
}
}
else if(jump==2){
dino_y++;
if(dino_y== DINO_INIT_Y){
jump=0;
}
}
if(tree_x<= (DINO_INIT_X+DINO_WIDTH) && tree_x>= (DINO_INIT_X+(DINO_WIDTH/2))){
if(dino_y>=(DINO_INIT_Y-3)){
gameOver(score);
break;
}
}
if(tree1_x<= (DINO_INIT_X+DINO_WIDTH) && tree1_x>= (DINO_INIT_X+(DINO_WIDTH/2))){
if(dino_y>=(DINO_INIT_Y-3)){
gameOver(score);
break;
}
}
displayScore(score);
moveTree(&tree_x,tree_type);
moveTree(&tree1_x,tree_type1);
moveDino(&dino_y);
display.drawLine(0, 54, 127, 54, SSD1306_WHITE);
tree_x--;
tree1_x--;
if(tree_x==0) {
tree_x = 127;
tree_type = random(0,1);
}
if(tree1_x==0) {
tree1_x = 195;
tree_type1 = random(0,1);
}
display.display();
}
}
void renderScene(int16_t i=0){
display.drawBitmap(10, 29, dino1, 25, 26, SSD1306_WHITE);
display.drawBitmap(50, TREE_Y, tree1, 11, 23, SSD1306_WHITE);
display.drawBitmap(100, TREE_Y, tree2, 22, 23, SSD1306_WHITE);
display.drawLine(0, 54, 127, 54, SSD1306_WHITE);
display.drawPixel(i, 60, SSD1306_WHITE);
}