150 lines
3.0 KiB
C++
150 lines
3.0 KiB
C++
#include "game.hpp"
|
|
|
|
Game::Game() : joystick(), display(), menu() {
|
|
state = (GameState) {
|
|
.pet = Pet(),
|
|
.lastActionTime = 0,
|
|
.isMenuOpen = false,
|
|
.shouldClearDisplay = false,
|
|
};
|
|
|
|
String items[] = {
|
|
"Feed",
|
|
"Play",
|
|
"Sleep",
|
|
"Clean"
|
|
};
|
|
|
|
menu.setItems(items);
|
|
}
|
|
|
|
void Game::begin() {
|
|
Serial.begin(9600);
|
|
while (!Serial) {
|
|
delay(10);
|
|
}
|
|
display.begin();
|
|
}
|
|
|
|
void Game::update() {
|
|
// If the pet is dead, we don't need to update its state
|
|
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.isMenuOpen) {
|
|
JoystickDirection direction = joystick.getDirection();
|
|
if (menu.updateCurrentItem(direction)) {
|
|
forceUpdate("Menu navigation");
|
|
}
|
|
|
|
// If the joystick is pressed, execute the current menu item
|
|
if (isPressed) {
|
|
state.isMenuOpen = false;
|
|
// Based on the current menu item, perform the corresponding action
|
|
switch (menu.getCurrentItemIndex()) {
|
|
case 0:
|
|
feed();
|
|
break;
|
|
case 1:
|
|
play();
|
|
break;
|
|
case 2:
|
|
sleep();
|
|
break;
|
|
case 3:
|
|
clean();
|
|
break;
|
|
}
|
|
forceUpdate("Menu action");
|
|
}
|
|
return;
|
|
}
|
|
|
|
// If the joystick is pressed and the menu is not open, open the menu
|
|
if (isPressed) {
|
|
state.isMenuOpen = true;
|
|
forceUpdate("Opening menu");
|
|
return;
|
|
}
|
|
|
|
// 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.pet.updateHunger(10);
|
|
state.pet.updateJoy(-5);
|
|
state.pet.updateEnergy(-5);
|
|
state.pet.updateCleanliness(-5);
|
|
|
|
state.lastActionTime = currentTime;
|
|
|
|
forceUpdate("Time-based stat update");
|
|
}
|
|
}
|
|
|
|
void Game::render() {
|
|
// Clear display if needed, and if the menu is open, redraw it
|
|
if (state.shouldClearDisplay) {
|
|
display.clear();
|
|
state.shouldClearDisplay = false;
|
|
|
|
if (state.isMenuOpen) {
|
|
display.drawMenu(menu);
|
|
Serial.println("Rendering menu");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// If the menu is open, we don't need to render the pet's stats
|
|
if (state.isMenuOpen) {
|
|
return;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
void Game::forceUpdate(String reason) {
|
|
if (!state.shouldClearDisplay) {
|
|
Serial.println("Forcing update: " + reason);
|
|
state.shouldClearDisplay = true;
|
|
}
|
|
}
|
|
|
|
void Game::feed() {
|
|
if (state.pet.isAlive) {
|
|
state.pet.updateHunger(-20);
|
|
}
|
|
}
|
|
|
|
void Game::play() {
|
|
if (state.pet.isAlive) {
|
|
state.pet.updateJoy(20);
|
|
}
|
|
}
|
|
|
|
void Game::sleep() {
|
|
if (state.pet.isAlive) {
|
|
state.pet.updateEnergy(20);
|
|
}
|
|
}
|
|
|
|
void Game::clean() {
|
|
if (state.pet.isAlive) {
|
|
state.pet.updateCleanliness(20);
|
|
}
|
|
}
|