Files
ardugotchi/src/game.cpp
T

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);
}
}