Skip to content

Commit 723ec11

Browse files
Remove intro screens from game apps and refactor UI
Intro screens and 'Press SELECT' prompts were removed from Break_the_Bricks, Decision_Compass, Helicopter_Game, and How_Many_Days_Until to unify app launching via the main menu. The UI.ino file was refactored for clearer menu navigation, idle animation, and integration of all apps, including Chrome Dino. Chrome_Dino.ino received code cleanup, improved comments, and better character slot management for LCD custom glyphs.
1 parent 9bc1404 commit 723ec11

6 files changed

Lines changed: 285 additions & 242 deletions

File tree

UI/Break_the_Bricks.ino

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,7 @@ static void BB_arkanoidsong();
107107
//-------------------------------------------------------------------
108108
void runBreakTheBricks()
109109
{
110-
// Clear the shared lcd (defined in UI.ino).
111-
lcd.clear();
112-
lcd.setCursor(0, 0);
113-
lcd.print(" Break Bricks ");
114-
lcd.setCursor(0, 1);
115-
lcd.print(" >Press SELECT< ");
116-
117-
// Wait for user to press SELECT before starting.
118-
while (BB_read_LCD_buttons() != BB_btnSELECT) {
119-
delay(10);
120-
}
110+
121111

122112
// Optional short beep or delay
123113
delay(200);

UI/Chrome_Dino.ino

Lines changed: 88 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,57 @@
11
#ifdef EMBED_DINO_IN_UI
2-
#define setup dinoSetup
3-
#define loop runChromeDino
4-
extern LiquidCrystal lcd;
5-
extern int read_LCD_buttons();
2+
// When embedded in the menu UI:
3+
// - rename Arduino entry points so UI can call one frame at a time
4+
// - reuse UI's lcd and button reader
5+
#define setup dinoSetup
6+
#define loop runChromeDino
7+
class LiquidCrystal; // forward declaration to avoid include order issues
8+
extern LiquidCrystal lcd;
9+
extern int read_LCD_buttons();
610
#endif
711

12+
/* Chrome Dino (16x2 LCD Keypad Shield)
13+
* - Dino pixels: UNCHANGED (CREA ELECTRONICA / Max Imagination two-cell style)
14+
* - Separate lanes: ground cactus (row 1) and bird (row 0)
15+
* - Score-based difficulty, clean Game Over
16+
* - Start/Restart with SELECT; Jump with UP or SELECT
17+
*/
18+
819
#include <LiquidCrystal.h>
9-
const uint8_t DINO_BTN_RIGHT = 0;
10-
const uint8_t DINO_BTN_UP = 1;
11-
const uint8_t DINO_BTN_DOWN = 2;
12-
const uint8_t DINO_BTN_LEFT = 3;
13-
const uint8_t DINO_BTN_SELECT = 4;
14-
const uint8_t DINO_BTN_NONE = 5;
20+
1521
#ifndef EMBED_DINO_IN_UI
1622
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
1723
#endif
1824

19-
// ---- Buttons via A0 ----
25+
// ---------- Button mapping (no BTN_* macros to avoid clashes) ----------
26+
#ifndef DINO_BTN_RIGHT
27+
const uint8_t DINO_BTN_RIGHT = 0;
28+
const uint8_t DINO_BTN_UP = 1;
29+
const uint8_t DINO_BTN_DOWN = 2;
30+
const uint8_t DINO_BTN_LEFT = 3;
31+
const uint8_t DINO_BTN_SELECT = 4;
32+
const uint8_t DINO_BTN_NONE = 5;
33+
#endif
34+
2035
#ifndef EMBED_DINO_IN_UI
36+
// Local reader only in standalone builds
2137
int read_LCD_buttons() {
2238
int adc = analogRead(A0);
23-
if (adc < 50) return BTN_RIGHT;
24-
if (adc < 195) return BTN_UP;
25-
if (adc < 380) return BTN_DOWN;
26-
if (adc < 555) return BTN_LEFT;
39+
if (adc < 50) return DINO_BTN_RIGHT;
40+
if (adc < 195) return DINO_BTN_UP;
41+
if (adc < 380) return DINO_BTN_DOWN;
42+
if (adc < 555) return DINO_BTN_LEFT;
2743
if (adc < 790) return DINO_BTN_SELECT;
28-
return BTN_NONE;
44+
return DINO_BTN_NONE;
2945
}
3046
#endif
3147

32-
static inline bool isJumpPressed(){ int b = read_LCD_buttons(); return (b == DINO_BTN_UP || b == DINO_BTN_SELECT); }
33-
34-
// ---- Custom characters ----
35-
// Index map: 0/1 right foot, 2/3 left foot, 4/5 idle, 6 cactus, 7 bird (animated)
48+
static inline bool isJumpPressed(){
49+
int b = read_LCD_buttons();
50+
return (b == DINO_BTN_UP || b == DINO_BTN_SELECT);
51+
}
3652

37-
// ---- Cactus ----
53+
// ---------- Custom characters (PRESERVED DINO PIXELS) ----------
54+
// CACTUS
3855
byte CACTUS[8] = {
3956
B00100,
4057
B00101,
@@ -46,57 +63,47 @@ byte CACTUS[8] = {
4663
B00100
4764
};
4865

49-
// --- Dino style from CREA ELECTRONICA / Max Imagination (two-cell wide) ---
66+
// Dino (two-cell style) — DO NOT CHANGE
5067
byte DINO_PARADO_PARTE_1[8] = {B00000, B00000, B00010, B00010, B00011, B00011, B00001, B00001};
5168
byte DINO_PARADO_PARTE_2[8] = {B00111, B00111, B00111, B00100, B11100, B11100, B11000, B01000};
5269
byte DINO_PIE_DERE_PART_1[8] = {B00000, B00000, B00010, B00010, B00011, B00011, B00001, B00001};
5370
byte DINO_PIE_DERE_PART_2[8] = {B00111, B00111, B00111, B00100, B11100, B11100, B11000, B00000};
5471
byte DINO_PIE_IZQU_PART_1[8] = {B00000, B00000, B00010, B00010, B00011, B00011, B00001, B00000};
5572
byte DINO_PIE_IZQU_PART_2[8] = {B00111, B00111, B00111, B00100, B11100, B11100, B11000, B01000};
5673

57-
// --- Upper obstacle: bird (animated wings on index 7) ---
58-
byte BIRD_UP[8] = {
59-
B00000,
60-
B00001,
61-
B00011,
62-
B00111,
63-
B01111,
64-
B11111,
65-
B00000,
66-
B00000
67-
};
68-
69-
byte BIRD_DOWN[8] = {
70-
B00000,
71-
B10000,
72-
B11000,
73-
B11100,
74-
B11110,
75-
B11111,
76-
B00000,
77-
B00000
74+
// Bird (animated into slot 7 only)
75+
byte BIRD_UP[8] = {B00000, B00001, B00011, B00111, B01111, B11111, B00000, B00000};
76+
byte BIRD_DOWN[8] = {B00000, B10000, B11000, B11100, B11110, B11111, B00000, B00000};
77+
78+
// Character slots (lock dino pixels in 0..6; only slot 7 animates)
79+
enum : uint8_t {
80+
CH_DINO_L0 = 0, // right-foot left cell
81+
CH_DINO_R0 = 1, // right-foot right cell
82+
CH_DINO_L1 = 2, // left-foot left cell
83+
CH_DINO_R1 = 3, // left-foot right cell
84+
CH_DINO_IDLE_L = 4,
85+
CH_DINO_IDLE_R = 5,
86+
CH_CACTUS = 6,
87+
CH_BIRD = 7
7888
};
7989

90+
// ---------- Game state ----------
8091
enum State { START, RUN, GAMEOVER };
8192
State state = START;
8293

8394
// Dino placement (two cells wide)
8495
const uint8_t DINO_COL1 = 1;
8596
const uint8_t DINO_COL2 = 2;
86-
8797
uint8_t dinoRow = 1; // 0 = top, 1 = bottom
8898
bool footSwap = false; // toggle run frames
8999

90100
// Obstacles
91-
int8_t cactusCol = 15;
92-
bool cactusActive = false;
93-
94-
int8_t birdCol = 15;
95-
bool birdActive = false;
101+
int8_t cactusCol = 15; bool cactusActive = false;
102+
int8_t birdCol = 15; bool birdActive = false;
96103

97104
// Difficulty/scaling
98105
uint8_t cactusSpawnChance = 2; // out of 10
99-
uint8_t birdSpawnChance = 0; // out of 10 (starts at 0 until score threshold)
106+
uint8_t birdSpawnChance = 0; // out of 10 (begins at 0)
100107

101108
// Timing
102109
unsigned long lastTick = 0;
@@ -111,7 +118,7 @@ const unsigned long jumpDuration = 520;
111118
// Score
112119
unsigned long score = 0;
113120

114-
// ---- Drawing helpers ----
121+
// ---------- Helpers ----------
115122
void drawScore() {
116123
lcd.setCursor(10, 0);
117124
char buf[7];
@@ -130,25 +137,25 @@ void clearDinoRow(uint8_t row) {
130137
}
131138

132139
void drawDino() {
133-
// Alternate legs; during jump we can keep alternating for effect
140+
// Alternate legs; dino pixels fixed to slots 0..5
134141
bool right = footSwap;
135-
uint8_t leftIdx = right ? 0 : 2; // left cell bitmap index group
136-
uint8_t rightIdx = right ? 1 : 3; // right cell bitmap index group
137-
lcd.setCursor(DINO_COL1, dinoRow); lcd.write(byte(leftIdx));
138-
lcd.setCursor(DINO_COL2, dinoRow); lcd.write(byte(rightIdx));
142+
uint8_t leftIdx = right ? CH_DINO_L0 : CH_DINO_L1;
143+
uint8_t rightIdx = right ? CH_DINO_R0 : CH_DINO_R1;
144+
lcd.setCursor(DINO_COL1, dinoRow); lcd.write(leftIdx);
145+
lcd.setCursor(DINO_COL2, dinoRow); lcd.write(rightIdx);
139146
}
140147

141148
inline void spawnCactus(){ cactusCol = 15; cactusActive = true; }
142149
inline void eraseCactus(int8_t c){ if (c>=0 && c<16){ lcd.setCursor(c,1); lcd.print(' ');} }
143-
inline void drawCactusAt(int8_t c){ if (c>=0 && c<16){ lcd.setCursor(c,1); lcd.write(byte(6)); } }
150+
inline void drawCactusAt(int8_t c){ if (c>=0 && c<16){ lcd.setCursor(c,1); lcd.write(CH_CACTUS); } }
144151

145152
inline void spawnBird(){ birdCol = 15; birdActive = true; }
146153
inline void eraseBird(int8_t c){ if (c>=0 && c<16){ lcd.setCursor(c,0); lcd.print(' ');} }
147154
inline void drawBirdAt(int8_t c){
148155
if (c>=0 && c<16){
149-
lcd.createChar(7, (footSwap ? BIRD_UP : BIRD_DOWN));
156+
lcd.createChar(CH_BIRD, (footSwap ? BIRD_UP : BIRD_DOWN)); // only slot 7 is updated
150157
lcd.setCursor(c,0);
151-
lcd.write(byte(7));
158+
lcd.write(CH_BIRD);
152159
}
153160
}
154161

@@ -164,7 +171,7 @@ void updateDifficulty() {
164171
else if (score < 20) { cactusSpawnChance = 3; birdSpawnChance = 2; }
165172
else if (score < 40) { cactusSpawnChance = 4; birdSpawnChance = 3; }
166173
else if (score < 60) { cactusSpawnChance = 5; birdSpawnChance = 4; }
167-
else { cactusSpawnChance = 6; birdSpawnChance = 5; } // still out of 10
174+
else { cactusSpawnChance = 6; birdSpawnChance = 5; } // out of 10
168175
}
169176

170177
bool checkCollision() {
@@ -191,32 +198,29 @@ void resetGame(bool toStart) {
191198
footSwap = false;
192199
jumping = false;
193200
dinoRow = 1;
194-
cactusActive = false;
195-
cactusCol = 15;
196-
birdActive = false;
197-
birdCol = 15;
198-
199-
if (toStart) {
200-
lcd.setCursor(0, 0); lcd.print(" CHROME DINO ");
201-
lcd.setCursor(0, 1); lcd.print(" >Press SELECT< ");
202-
state = START;
203-
} else {
201+
cactusActive = false; cactusCol = 15;
202+
birdActive = false; birdCol = 15;
203+
204+
204205
showHUD();
205206
state = RUN;
206-
}
207+
207208
}
208209

210+
// ---------- Arduino entry points (renamed when embedded) ----------
209211
void setup() {
210212
lcd.begin(16, 2);
211213
randomSeed(analogRead(A0));
212-
// 0/1 = right foot; 2/3 = left foot; 4/5 = idle; 6 = cactus
213-
lcd.createChar(0, DINO_PIE_DERE_PART_1);
214-
lcd.createChar(1, DINO_PIE_DERE_PART_2);
215-
lcd.createChar(2, DINO_PIE_IZQU_PART_1);
216-
lcd.createChar(3, DINO_PIE_IZQU_PART_2);
217-
lcd.createChar(4, DINO_PARADO_PARTE_1);
218-
lcd.createChar(5, DINO_PARADO_PARTE_2);
219-
lcd.createChar(6, CACTUS);
214+
215+
// Load fixed glyphs (dino & cactus). Only bird slot is animated later.
216+
lcd.createChar(CH_DINO_L0, DINO_PIE_DERE_PART_1);
217+
lcd.createChar(CH_DINO_R0, DINO_PIE_DERE_PART_2);
218+
lcd.createChar(CH_DINO_L1, DINO_PIE_IZQU_PART_1);
219+
lcd.createChar(CH_DINO_R1, DINO_PIE_IZQU_PART_2);
220+
lcd.createChar(CH_DINO_IDLE_L, DINO_PARADO_PARTE_1);
221+
lcd.createChar(CH_DINO_IDLE_R, DINO_PARADO_PARTE_2);
222+
lcd.createChar(CH_CACTUS, CACTUS);
223+
220224
resetGame(true);
221225
}
222226

@@ -255,10 +259,11 @@ void loop() {
255259
lastTick = now;
256260
footSwap = !footSwap;
257261

258-
// Cactus movement
262+
// Difficulty
259263
updateDifficulty();
264+
265+
// Cactus movement / spawn
260266
if (!cactusActive) {
261-
// avoid spawning right on top of a fresh bird near the edge
262267
bool birdTooClose = (birdActive && birdCol > 11);
263268
if (!birdTooClose && (random(0, 10) < cactusSpawnChance || score == 0)) spawnCactus();
264269
} else {
@@ -273,9 +278,8 @@ void loop() {
273278
}
274279
}
275280

276-
// Bird movement
281+
// Bird movement / spawn
277282
if (!birdActive) {
278-
// Start birds only after a few points and keep spacing from fresh cactus
279283
bool cactusTooClose = (cactusActive && cactusCol > 11);
280284
if (!cactusTooClose && score > 5 && random(0, 10) < birdSpawnChance) spawnBird();
281285
} else {
@@ -296,7 +300,7 @@ void loop() {
296300
// Collision
297301
if (checkCollision()) {
298302
enterGameOver();
299-
return;
303+
return; // stop processing this frame
300304
}
301305
}
302306
} break;

UI/Decision_Compass.ino

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,12 @@ void runDecisionCompass()
4949
// Initialize random
5050
randomSeed(analogRead(A1));
5151

52-
// Clear the shared lcd from UI.ino
53-
lcd.clear();
54-
lcd.setCursor(0, 0);
55-
lcd.print("Decision Compass");
56-
5752
// Main loop: press SELECT to pick random response, press RIGHT/LEFT to scroll
5853
while (true) {
5954
int buttonValue = analogRead(A0);
6055

61-
// If user presses SELECT
62-
if (buttonValue > (DC_SELECT_BUTTON - 10) && buttonValue < (DC_SELECT_BUTTON + 10)) {
6356
DC_showRandomResponse();
64-
delay(500);
65-
}
66-
57+
6758
// If user presses RIGHT
6859
if (buttonValue > (DC_RIGHT_BUTTON - 10) && buttonValue < (DC_RIGHT_BUTTON + 10)) {
6960
DC_scrollText(1);

UI/Helicopter_Game.ino

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
void runHelicopterGame() {
22
const int UP_BUTTON = 131;
33
const int DOWN_BUTTON = 309;
4-
const int BTN_SELECT = 790;
5-
4+
5+
extern int read_LCD_buttons();
6+
const int BTN_SELECT_ENUM = 4;
7+
68
int heliRow = 0;
79
int obstacleX[5];
810
int obstacleY[5];
@@ -38,11 +40,6 @@ void runHelicopterGame() {
3840
resetGame();
3941

4042
lcd.clear();
41-
lcd.setCursor(0, 0);
42-
lcd.print("Helicopter Game");
43-
lcd.setCursor(0, 1);
44-
lcd.print(" >Press SELECT< ");
45-
while (read_LCD_buttons() != BTN_SELECT) { delay(50); }
4643

4744
while (true) {
4845
int btnVal = analogRead(A0);
@@ -73,13 +70,13 @@ void runHelicopterGame() {
7370
delay(200);
7471
if (gameOver) {
7572
lcd.clear();
76-
lcd.setCursor(3, 0);
73+
lcd.setCursor(0, 0);
7774
lcd.print(" GAME OVER ");
78-
lcd.setCursor(2, 1);
75+
lcd.setCursor(0, 1);
7976
lcd.print(" >Press SELECT< ");
8077
while (true) {
8178
int val = analogRead(A0);
82-
if (val > (BTN_SELECT - 10) && val < (BTN_SELECT + 10)) {
79+
if (read_LCD_buttons() == BTN_SELECT_ENUM) {
8380
resetGame();
8481
gameOver = false;
8582
break;

UI/How_Many_Days_Until.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ static void HMD_showIntro()
129129
{
130130
lcd.clear();
131131
lcd.setCursor(0, 0);
132-
lcd.print("How Many Days?");
133-
lcd.setCursor(1, 1);
132+
lcd.print(" How Many Days? ");
133+
lcd.setCursor(0, 1);
134134
lcd.print(" >Press SELECT< ");
135135
}
136136

0 commit comments

Comments
 (0)