feat(game): include pet in state

This commit is contained in:
2026-04-29 00:41:37 +02:00
parent 5b763a33bc
commit ea3632326b
2 changed files with 47 additions and 52 deletions
+5 -8
View File
@@ -3,20 +3,17 @@
#include "joystick.hpp"
#include "display.hpp"
#include "menu.hpp"
#include "pet.hpp"
#define ACTION_INTERVAL 60000 // 1 minute
#define MAXIMUM_STAT 100
typedef struct {
bool dead;
bool menuOpen;
int hunger;
int joy;
int energy;
int cleanliness;
Pet pet;
uint64_t lastActionTime;
bool shouldClear;
bool isMenuOpen;
bool shouldClearDisplay;
} GameState;
class Game {
+42 -44
View File
@@ -2,14 +2,10 @@
Game::Game() : joystick(), display(), menu() {
state = (GameState) {
.dead = false,
.menuOpen = false,
.hunger = 0,
.joy = 100,
.energy = 100,
.cleanliness = 100,
.pet = Pet(),
.lastActionTime = 0,
.shouldClear = false,
.isMenuOpen = false,
.shouldClearDisplay = false,
};
String items[] = {
@@ -32,14 +28,14 @@ void Game::begin() {
void Game::update() {
// If the pet is dead, we don't need to update its state
if (state.dead) {
if (!state.pet.isAlive) {
return;
}
bool isPressed = joystick.isPressed();
// If the menu is open, we don't need to update the pet's state
if (state.menuOpen) {
if (state.isMenuOpen) {
JoystickDirection direction = joystick.getDirection();
if (menu.updateCurrentItem(direction)) {
forceUpdate("Menu navigation");
@@ -47,7 +43,7 @@ void Game::update() {
// If the joystick is pressed, execute the current menu item
if (isPressed) {
state.menuOpen = false;
state.isMenuOpen = false;
// Based on the current menu item, perform the corresponding action
switch (menu.getCurrentItemIndex()) {
case 0:
@@ -70,7 +66,7 @@ void Game::update() {
// If the joystick is pressed and the menu is not open, open the menu
if (isPressed) {
state.menuOpen = true;
state.isMenuOpen = true;
forceUpdate("Opening menu");
return;
}
@@ -78,74 +74,76 @@ void Game::update() {
// Update the pet's stats based on the time elapsed since the last action
uint64_t currentTime = millis();
if (currentTime - state.lastActionTime >= ACTION_INTERVAL) {
state.hunger += 10;
state.joy -= 5;
state.energy -= 5;
state.cleanliness -= 5;
state.pet.updateHunger(10);
state.pet.updateJoy(-5);
state.pet.updateEnergy(-5);
state.pet.updateCleanliness(-5);
state.lastActionTime = currentTime;
forceUpdate("Time-based stat update");
}
// Check if the pet has died from any of the conditions
bool starvedToDeath = state.hunger >= MAXIMUM_STAT;
bool diedOfBoredom = state.joy <= -MAXIMUM_STAT;
bool diedOfExhaustion = state.energy <= -MAXIMUM_STAT;
bool diedOfFilth = state.cleanliness <= -MAXIMUM_STAT;
state.dead = starvedToDeath || diedOfBoredom || diedOfExhaustion || diedOfFilth;
}
void Game::render() {
if (state.shouldClear) {
// Clear display if needed, and if the menu is open, redraw it
if (state.shouldClearDisplay) {
display.clear();
state.shouldClear = false;
state.shouldClearDisplay = false;
if (state.menuOpen) {
if (state.isMenuOpen) {
display.drawMenu(menu);
Serial.println("Rendering menu");
return;
}
}
if (state.menuOpen) {
// If the menu is open, we don't need to render the pet's stats
if (state.isMenuOpen) {
return;
}
if (state.dead) {
display.getLCD().print("Your pet has died.");
// If the pet is dead, display a message and return
if (!state.pet.isAlive) {
String buffer[4] = {
"Your pet has died",
state.pet.getReasonForDeath(),
"Reset the device",
"to start over"
};
display.drawBuffer(buffer);
return;
}
display.getLCD().setCursor(0, 0);
display.getLCD().print("H: " + String(state.hunger));
display.getLCD().setCursor(0, 1);
display.getLCD().print("J: " + String(state.joy));
display.getLCD().setCursor(0, 2);
display.getLCD().print("E: " + String(state.energy));
display.getLCD().setCursor(0, 3);
display.getLCD().print("C: " + String(state.cleanliness));
}
void Game::forceUpdate(String reason) {
if (!state.shouldClear) {
if (!state.shouldClearDisplay) {
Serial.println("Forcing update: " + reason);
state.shouldClear = true;
state.shouldClearDisplay = true;
}
}
void Game::feed() {
state.hunger += 20;
if (state.pet.isAlive) {
state.pet.updateHunger(-20);
}
}
void Game::play() {
state.joy += 20;
if (state.pet.isAlive) {
state.pet.updateJoy(20);
}
}
void Game::sleep() {
state.energy += 20;
if (state.pet.isAlive) {
state.pet.updateEnergy(20);
}
}
void Game::clean() {
state.cleanliness += 20;
if (state.pet.isAlive) {
state.pet.updateCleanliness(20);
}
}