feat(game): add custom pet icon

This commit is contained in:
2026-04-29 01:00:02 +02:00
parent 6fffa3e879
commit c6923c209c
6 changed files with 67 additions and 17 deletions
+1
View File
@@ -2,6 +2,7 @@
/* /*
* A header file to store all the constants used in the project. * A header file to store all the constants used in the project.
*/ */
#include <Arduino.h>
#define LCD_I2C_ADDRESS 0x27 #define LCD_I2C_ADDRESS 0x27
#define LCD_COLS 20 #define LCD_COLS 20
#define LCD_ROWS 4 #define LCD_ROWS 4
+2
View File
@@ -3,6 +3,7 @@
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#include "constants.hpp" #include "constants.hpp"
#include "menu.hpp" #include "menu.hpp"
#include "pet.hpp"
/* /*
* A helper class to facilitate drawing on a HD44780 LCD display. * A helper class to facilitate drawing on a HD44780 LCD display.
@@ -13,6 +14,7 @@ class Display {
void begin(); void begin();
void clear(); void clear();
void drawPet(Pet& pet);
void drawBuffer(String buffer[]); void drawBuffer(String buffer[]);
void drawMenu(Menu& menu); void drawMenu(Menu& menu);
+5
View File
@@ -11,6 +11,11 @@ class Pet {
void updateJoy(int8_t delta); void updateJoy(int8_t delta);
void updateEnergy(int8_t delta); void updateEnergy(int8_t delta);
void updateCleanliness(int8_t delta); void updateCleanliness(int8_t delta);
int8_t getHunger() const;
int8_t getJoy() const;
int8_t getEnergy() const;
int8_t getCleanliness() const;
String getReasonForDeath() const; String getReasonForDeath() const;
private: private:
int8_t hunger; int8_t hunger;
+28
View File
@@ -4,8 +4,20 @@
Display::Display() : lcd(LCD_I2C_ADDRESS, LCD_COLS, LCD_ROWS) {} Display::Display() : lcd(LCD_I2C_ADDRESS, LCD_COLS, LCD_ROWS) {}
void Display::begin() { void Display::begin() {
byte CUSTOM_CHAR_PET[] = {
B00100,
B01110,
B11111,
B10101,
B11111,
B11111,
B10001,
B11111
};
lcd.init(); lcd.init();
lcd.backlight(); lcd.backlight();
lcd.createChar(0, CUSTOM_CHAR_PET); // Create a custom character for the pet
} }
void Display::clear() { void Display::clear() {
@@ -20,6 +32,22 @@ void Display::drawBuffer(String buffer[]) {
} }
} }
void Display::drawPet(Pet &pet) {
clear();
lcd.setCursor(0, 0);
lcd.print("Hunger: " + String(pet.getHunger()));
lcd.setCursor(0, 1);
lcd.print("Joy: " + String(pet.getJoy()));
lcd.setCursor(0, 2);
lcd.print("Energy: " + String(pet.getEnergy()));
lcd.setCursor(0, 3);
lcd.print("Cleanliness: " + String(pet.getCleanliness()));
lcd.setCursor(LCD_COLS - 2, LCD_ROWS / 2 - 1); // Position the pet
lcd.write(byte(0)); // Draw the custom pet character
}
void Display::drawMenu(Menu &menu) { void Display::drawMenu(Menu &menu) {
clear(); clear();
size_t currentItemIndex = menu.getCurrentItemIndex(); size_t currentItemIndex = menu.getCurrentItemIndex();
+13 -15
View File
@@ -5,7 +5,7 @@ Game::Game() : joystick(), display(), menu() {
.pet = Pet(), .pet = Pet(),
.lastActionTime = 0, .lastActionTime = 0,
.isMenuOpen = false, .isMenuOpen = false,
.shouldClearDisplay = false, .shouldClearDisplay = true,
}; };
String items[] = { String items[] = {
@@ -86,35 +86,33 @@ void Game::update() {
} }
void Game::render() { void Game::render() {
// Clear display if needed, and if the menu is open, redraw it if (!state.shouldClearDisplay) {
if (state.shouldClearDisplay) { return;
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 state.shouldClearDisplay = false;
if (state.isMenuOpen) { if (state.isMenuOpen) {
display.drawMenu(menu);
Serial.println("Rendering menu");
return; return;
} }
// If the pet is dead, display a message and return // If the pet is dead, display a message and return
if (!state.pet.isAlive) { if (!state.pet.isAlive) {
String buffer[LCD_ROWS] = { String buffer[LCD_ROWS] = {
"Your pet has died", "Your pet has died of",
state.pet.getReasonForDeath(), state.pet.getReasonForDeath() + ".",
"Reset the device", "Reset the device",
"to start over" "to start over."
}; };
display.drawBuffer(buffer); display.drawBuffer(buffer);
return; return;
} }
// Render the pet's stats on the display
display.drawPet(state.pet);
} }
void Game::forceUpdate(String reason) { void Game::forceUpdate(String reason) {
+18 -2
View File
@@ -8,13 +8,13 @@ void Pet::updateHunger(int8_t delta) {
if (hunger < 0) { if (hunger < 0) {
isAlive = false; isAlive = false;
reasonForDeath = "starvation"; reasonForDeath = "overfeeding";
return; return;
} }
if (hunger > MAXIMUM_STAT) { if (hunger > MAXIMUM_STAT) {
isAlive = false; isAlive = false;
reasonForDeath = "overfeeding"; reasonForDeath = "starvation";
} }
} }
@@ -63,6 +63,22 @@ void Pet::updateCleanliness(int8_t delta) {
} }
} }
int8_t Pet::getHunger() const {
return hunger;
}
int8_t Pet::getJoy() const {
return joy;
}
int8_t Pet::getEnergy() const {
return energy;
}
int8_t Pet::getCleanliness() const {
return cleanliness;
}
String Pet::getReasonForDeath() const { String Pet::getReasonForDeath() const {
return reasonForDeath; return reasonForDeath;
} }