-
Notifications
You must be signed in to change notification settings - Fork 0
games
Six mini-games live in lib/GAMES/, launched from Menu → Games. They run
as carousel overlays (CarouselManager::activateGame) — the underlying
carousel screen stops ticking/animating while a game is active (only
background housekeeping like the status bar, idle-sleep and input polling
keep running) and every tick/button routes to the game instead, until it
exits. Eye LEDs are suppressed while a game is on screen.
stateDiagram-v2
[*] --> IDLE: activateGame → init()
IDLE --> PLAYING: OK (onStart)
IDLE --> [*]: CANCEL (clearGame)
PLAYING --> GAME_OVER: endGame(result)
PLAYING --> [*]: CANCEL
GAME_OVER --> PLAYING: OK (restart)
GAME_OVER --> [*]: CANCEL
GameElement (base class) provides:
-
Idle/title screen with per-game splash art (
drawSplashArt(), top ~30 px) and a blinking "OK start / CANCEL exit" hint. -
Score screen on
endGame(msg)— shows_scoreand an optional result message; OK restarts, CANCEL leaves. - Subclass contract:
onStart()(reset state),onTick(now)(frame),onInput(button)(game keys). The base class already consumes OK/CANCEL in IDLE/GAME_OVER states.
The panic-stop key (FUNC_1_DOWN) still works during games — it is
handled by the carousel before input routing.
| Game | Menu label | Play mechanics (keys = right joystick — games receive GEM_KEY_UP/DOWN/LEFT/RIGHT/OK, the same channel as every other screen; the left joystick's FUNC keys are swallowed by the carousel while a game is active, except panic stop) |
|---|---|---|
GameDino |
Dino Runner | Endless runner: jump (with grace window) and duck under birds; speed ramps up |
GameSnake |
Snake | 25×10 grid, 3 lives (running into a border or yourself costs a life and resets the snake, doesn't end the run outright); step timer speeds up as you eat |
GameBreakout |
Breakout | Paddle + bricks |
GameConnect4 |
Connect 4 | You vs. a built-in AI (win-if-possible → block-player-win → center-preference heuristic) on a 7-column board |
GameInvaders |
Invaders | 5×3 alien grid marching, player ship + single bullet |
GameWumpus |
Hunt Wumpus | Classic dodecahedron cave (20 rooms), 5 arrows, pits/bats/wumpus clues; cursor picks one of 3 tunnels, shoot mode toggles |
All games draw with Adafruit_GFX primitives at text size 1 into the shared
100×48 canvas and flush with updateWholeScreen().
Pixel-accurate renderings of each game's title, in-game and game-over
screens, generated by tools/lcd_render
(a host-side reimplementation of Adafruit_GFX driven by the real draw-call
sequences — see that folder's render_all.py for how to regenerate these
after a UI change).






- Subclass
GameElement, implementonStart/onTick/onInput(+ optionaldrawSplashArt). - Instantiate it in
main.cppand register beforecarousel.begin():menuEl.addGame(&myGame, "My Game"); -
MenuElement::MAX_GAMESis 7 (already bumped from 6 forgame_tiltmaze.cpp, which exists inlib/GAMES/but is currently commented out of registration inmain.cpp— not reachable from the menu) — raise it further if you add another.
A lazy-loading scheme (placement-new on launch) was evaluated and rejected: it would only save ~500 B of static RAM and adds lifetime-management risk.