The Chrome Dino Game on an LCD Shield
Quote from Matoo robot on 2024年7月2日, pm5:12The Chrome dinosaur game that is now on an Arduino LCD shield!
Project description
Somehow, I am very bad at coming up with ideas.
It's just like that.
But anyway, I was browsing the $ Project Hub $ and I found $ this project $ . It was a great project!
But I still made my own version in Arduino C because 1. I wanted to make something and 2. I don't want to download another thing on my computer.
(I still would highly recommend checking it out! Link is $ here $ !)
Here are some pictures:
Features
- Splash screen that waits until you are ready.
- When you are holding the SELECT button to jump, score is stopped from incrementing so that you can't just hold down the button the entire time.
- Custom characters for the dinosaur, cacti, birds, and blocks.
- Death screen.
- High score saved in internal EEPROM.
- Ability to erase high score using "secret" code. (You can read the code and figure out the code!)
How to Play
- Press SELECT to start.
- Pres SELECT to jump.
- When you die, reset using the RESET button.
- Repeat until you are sick of it.
- To erase high score, click DOWN when you are at the splash screen. Then increment/decrement the code using the UP and DOWN buttons respectively to change the code. Default code is 123. Press SELECT to enter. Hi score should be erased.
How the Code Works
First, I include all of the necessary libraries and the bitmaps. Then, I define an object called lcd . I define a bunch of variables and #defines. Then I write an array as a buffer for holding what goes on the screen. Then I define more variables.
Then setup starts. I do all of the necessary stuff, like creating the characters and showing the splash screen.
We have loop next. I define some timing variables, like in blinkwithoutdelay . I do the check if the time has passed long enough. Then, I use the random function to decide when and what to put in the buffer. After that, I shift all of the elements in the buffer down one using a for loop. Then it checks whether to add the score or not because as I said earlier, when you are jumping you cannot get any points.
Then I draw the barriers next, as you see the blocks bitmap .
Then I check whether the SELECT (jump) button is pressed. It then modifies the buffer to show whether the dinosaur is jumping or not.
The next code checks whether dinosaur has been airborne long enough so that the dinosaur can come down.
This is where the code checks whether there is an obstacle in the way.
If the dinosaur didn't crash, then the Arduino updates the lcd and prints the score. Else, it shows the death screen.
Then the final code is not required-it blinks the LED. If you are having problems with timing, then you could remove/comment the blink code out.
Last, the Arduino build process includes the Functions tab at the end of the sketch for us. This includes lots of functions that are used throughout the code.
Code
bitmaps.h
Upload as a seperate tab named bitmaps.h
// Bitmaps-Do not modify byte dino[8] = { 0b00000, 0b00111, 0b00111, 0b10110, 0b11111, 0b01010, 0b01010, 0b00000 }; byte cacti[8] = { 0b00100, 0b00101, 0b10101, 0b10101, 0b10111, 0b11100, 0b00100, 0b00000 }; byte bird[8] = { 0b00000, 0b00100, 0b01100, 0b11110, 0b00111, 0b00110, 0b00100, 0b00000 }; byte block[8] = { 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 };
Chrome_Dino_Game_on_LCD
c_cpp
Paste into editor as main sketch
#include <LiquidCrystal.h> #include <EEPROM.h> #include "bitmaps.h" LiquidCrystal lcd(8, 9, 4, 5, 6, 7); int adc_key_in = 0; #define btnRIGHT 0 #define btnUP 1 #define btnDOWN 2 #define btnLEFT 3 #define btnSELECT 4 #define btnNONE 5 byte runnerArea[16] {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}; byte jump = 32; int score = 0; bool freeze_score = 0; byte correct_code = 123; unsigned long previousMillis = 0; unsigned long previousMillisLED = 0; unsigned long jumpTime = 0; const int jumpLength = 500; #define checkSafe runnerArea[1] == 32 || runnerArea[1] == 0 const byte chance_of_ob = 15; int speedOfScroller = 300; void setup() { lcd.begin(16, 2); Serial.begin(9600); lcd.createChar(0, dino); lcd.createChar(1, cacti); lcd.createChar(2, bird); lcd.createChar(3, block); pinMode(A0, INPUT); pinMode(A1, INPUT); pinMode(13, OUTPUT); randomSeed(A1); lcd.clear(); showSplashScreen(1000, true); } void loop() { unsigned long currentMillis = millis(); unsigned long currentMillisOb = millis(); if (currentMillisOb - previousMillis >= speedOfScroller) { previousMillis = currentMillisOb; if (random(chance_of_ob) == 0) { runnerArea[15] = 1; } else if (random(chance_of_ob) == 1) { runnerArea[15] = 2; } else { runnerArea[15] = 32; } for (int i = 0; i <= 15; i++) { runnerArea[i] = runnerArea[i + 1]; } if (freeze_score == 0) { score++; } } drawBarrier(); if (read_LCD_buttons() == btnSELECT) { // runnerArea[1] = 32; if (runnerArea[1] != 32 && (runnerArea[1] != 1 || runnerArea[1] != 2)) { runnerArea[1] = 32; } jump = 0; freeze_score = 1; jumpTime = millis(); } if (millis() - jumpTime >= jumpLength) { if (checkSafe) { runnerArea[1] = 0; jump = 32; freeze_score = 0; } else { showCrashScreen(); } } updateLcd(); printScore(); if (millis() - previousMillisLED >= 500) { previousMillisLED = currentMillis; digitalWrite(13, !digitalRead(13)); } }
bitmaps.h
h
Upload as a seperate tab named bitmaps.h
// Bitmaps-Do not modify
byte dino[8] = {
0b00000,
0b00111,
0b00111,
0b10110,
0b11111,
0b01010,
0b01010,
0b00000
};
byte
cacti[8] = {
0b00100,
0b00101,
0b10101,
0b10101,
0b10111,
0b11100,
0b00100,
0b00000
};
byte bird[8] = {
0b00000,
0b00100,
0b01100,
0b11110,
0b00111,
0b00110,
0b00100,
0b00000
};
byte block[8] = {
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111
};
The Chrome dinosaur game that is now on an Arduino LCD shield!
Project description
Somehow, I am very bad at coming up with ideas.
It's just like that.
But anyway, I was browsing the $ Project Hub $ and I found $ this project $ . It was a great project!
But I still made my own version in Arduino C because 1. I wanted to make something and 2. I don't want to download another thing on my computer.
(I still would highly recommend checking it out! Link is $ here $ !)
Here are some pictures:
Features
- Splash screen that waits until you are ready.
- When you are holding the SELECT button to jump, score is stopped from incrementing so that you can't just hold down the button the entire time.
- Custom characters for the dinosaur, cacti, birds, and blocks.
- Death screen.
- High score saved in internal EEPROM.
- Ability to erase high score using "secret" code. (You can read the code and figure out the code!)
How to Play
- Press SELECT to start.
- Pres SELECT to jump.
- When you die, reset using the RESET button.
- Repeat until you are sick of it.
- To erase high score, click DOWN when you are at the splash screen. Then increment/decrement the code using the UP and DOWN buttons respectively to change the code. Default code is 123. Press SELECT to enter. Hi score should be erased.
How the Code Works
First, I include all of the necessary libraries and the bitmaps. Then, I define an object called lcd . I define a bunch of variables and #defines. Then I write an array as a buffer for holding what goes on the screen. Then I define more variables.
Then setup starts. I do all of the necessary stuff, like creating the characters and showing the splash screen.
We have loop next. I define some timing variables, like in blinkwithoutdelay . I do the check if the time has passed long enough. Then, I use the random function to decide when and what to put in the buffer. After that, I shift all of the elements in the buffer down one using a for loop. Then it checks whether to add the score or not because as I said earlier, when you are jumping you cannot get any points.
Then I draw the barriers next, as you see the blocks bitmap .
Then I check whether the SELECT (jump) button is pressed. It then modifies the buffer to show whether the dinosaur is jumping or not.
The next code checks whether dinosaur has been airborne long enough so that the dinosaur can come down.
This is where the code checks whether there is an obstacle in the way.
If the dinosaur didn't crash, then the Arduino updates the lcd and prints the score. Else, it shows the death screen.
Then the final code is not required-it blinks the LED. If you are having problems with timing, then you could remove/comment the blink code out.
Last, the Arduino build process includes the Functions tab at the end of the sketch for us. This includes lots of functions that are used throughout the code.
Code
bitmaps.h
Upload as a seperate tab named bitmaps.h
// Bitmaps-Do not modify
byte dino[8] = {
0b00000,
0b00111,
0b00111,
0b10110,
0b11111,
0b01010,
0b01010,
0b00000
};
byte cacti[8] = {
0b00100,
0b00101,
0b10101,
0b10101,
0b10111,
0b11100,
0b00100,
0b00000
};
byte bird[8] = {
0b00000,
0b00100,
0b01100,
0b11110,
0b00111,
0b00110,
0b00100,
0b00000
};
byte block[8] = {
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111
};
Chrome_Dino_Game_on_LCD
c_cpp
Paste into editor as main sketch
#include <LiquidCrystal.h>
#include <EEPROM.h>
#include "bitmaps.h"
LiquidCrystal
lcd(8, 9, 4, 5, 6, 7);
int adc_key_in = 0;
#define btnRIGHT 0
#define
btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define
btnNONE 5
byte runnerArea[16] {32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32};
byte jump = 32;
int score = 0;
bool freeze_score
= 0;
byte correct_code = 123;
unsigned long previousMillis = 0;
unsigned
long previousMillisLED = 0;
unsigned long jumpTime = 0;
const int jumpLength
= 500;
#define checkSafe runnerArea[1] == 32 || runnerArea[1] == 0
const
byte chance_of_ob = 15;
int speedOfScroller = 300;
void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
lcd.createChar(0, dino);
lcd.createChar(1, cacti);
lcd.createChar(2, bird);
lcd.createChar(3,
block);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(13, OUTPUT);
randomSeed(A1);
lcd.clear();
showSplashScreen(1000, true);
}
void
loop() {
unsigned long currentMillis = millis();
unsigned long currentMillisOb
= millis();
if (currentMillisOb - previousMillis >= speedOfScroller) {
previousMillis = currentMillisOb;
if (random(chance_of_ob) == 0) {
runnerArea[15] = 1;
} else if (random(chance_of_ob) == 1) {
runnerArea[15]
= 2;
} else {
runnerArea[15] = 32;
}
for (int i =
0; i <= 15; i++) {
runnerArea[i] = runnerArea[i + 1];
}
if
(freeze_score == 0) {
score++;
}
}
drawBarrier();
if (read_LCD_buttons() == btnSELECT) {
// runnerArea[1] = 32;
if
(runnerArea[1] != 32 && (runnerArea[1] != 1 || runnerArea[1] != 2)) {
runnerArea[1]
= 32;
}
jump = 0;
freeze_score = 1;
jumpTime = millis();
}
if (millis() - jumpTime >= jumpLength) {
if (checkSafe) {
runnerArea[1]
= 0;
jump = 32;
freeze_score = 0;
} else {
showCrashScreen();
}
}
updateLcd();
printScore();
if (millis() - previousMillisLED
>= 500) {
previousMillisLED = currentMillis;
digitalWrite(13, !digitalRead(13));
}
}
bitmaps.h
h
Upload as a seperate tab named bitmaps.h
// Bitmaps-Do not modify
byte dino[8] = {
0b00000,
0b00111,
0b00111,
0b10110,
0b11111,
0b01010,
0b01010,
0b00000
};
byte
cacti[8] = {
0b00100,
0b00101,
0b10101,
0b10101,
0b10111,
0b11100,
0b00100,
0b00000
};
byte bird[8] = {
0b00000,
0b00100,
0b01100,
0b11110,
0b00111,
0b00110,
0b00100,
0b00000
};
byte block[8] = {
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111
};