strontgame/strontgame.ino

221 lines
7.5 KiB
C++

#include <Wire.h>
#include <Adafruit_SSD1306.h>
// OLED display size
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Create display object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Pin assignments
#define FEED_BUTTON_PIN 2
#define POOP_BUTTON_PIN 3
// Game constants
#define MAX_FOOD 100
#define MAX_POOP 100
#define FOOD_BAR_Y 0
#define POOP_BAR_Y 8
#define BAR_HEIGHT 7
#define BAR_WIDTH 120
#define BAR_X 4
#define BAR_LABEL_X 0
#define BAR_LABEL_WIDTH 4
#define YELLOW_BAR_HEIGHT 16
// Game state
int food = MAX_FOOD / 2;
int poop = MAX_POOP / 2;
bool gameOver = false;
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 200; // ms
void drawBars() {
// Draw yellow background for status area
display.fillRect(0, 0, SCREEN_WIDTH, YELLOW_BAR_HEIGHT, SSD1306_WHITE);
// Draw Food bar label
display.setTextColor(SSD1306_BLACK);
display.setTextSize(1);
display.setCursor(BAR_X, FOOD_BAR_Y);
display.print("FOOD");
// Draw Poop bar label
display.setCursor(BAR_X, POOP_BAR_Y);
display.print("POOP");
// Draw Food bar
int foodBarLen = (food * (BAR_WIDTH - 30)) / MAX_FOOD; // leave space for label
display.fillRect(BAR_X + 34, FOOD_BAR_Y, foodBarLen, BAR_HEIGHT, SSD1306_BLACK);
display.drawRect(BAR_X + 34, FOOD_BAR_Y, BAR_WIDTH - 30, BAR_HEIGHT, SSD1306_BLACK);
// Draw Poop bar
int poopBarLen = (poop * (BAR_WIDTH - 30)) / MAX_POOP;
display.fillRect(BAR_X + 34, POOP_BAR_Y, poopBarLen, BAR_HEIGHT, SSD1306_BLACK);
display.drawRect(BAR_X + 34, POOP_BAR_Y, BAR_WIDTH - 30, BAR_HEIGHT, SSD1306_BLACK);
display.setTextSize(1);
}
void drawStickFigure(int frame) {
// Draw a simple stick figure in the blue area (below yellow bar)
int baseY = 24;
int centerX = SCREEN_WIDTH / 2;
// Head
display.drawCircle(centerX, baseY, 6, SSD1306_WHITE);
// Body
display.drawLine(centerX, baseY + 6, centerX, baseY + 24, SSD1306_WHITE);
// Arms (simple animation)
if (frame % 2 == 0) {
display.drawLine(centerX, baseY + 10, centerX - 10, baseY + 18, SSD1306_WHITE);
display.drawLine(centerX, baseY + 10, centerX + 10, baseY + 18, SSD1306_WHITE);
} else {
display.drawLine(centerX, baseY + 10, centerX - 14, baseY + 14, SSD1306_WHITE);
display.drawLine(centerX, baseY + 10, centerX + 14, baseY + 14, SSD1306_WHITE);
}
// Legs
display.drawLine(centerX, baseY + 24, centerX - 10, baseY + 40, SSD1306_WHITE);
display.drawLine(centerX, baseY + 24, centerX + 10, baseY + 40, SSD1306_WHITE);
}
void drawStinkyPoop() {
// Draw a simple stinky poop in the blue area
int baseY = 32;
int centerX = SCREEN_WIDTH / 2;
// Poop base
display.fillCircle(centerX, baseY + 16, 8, SSD1306_WHITE);
display.fillCircle(centerX, baseY + 8, 6, SSD1306_WHITE);
display.fillCircle(centerX, baseY, 4, SSD1306_WHITE);
// Stink lines
display.drawLine(centerX - 6, baseY - 4, centerX - 6, baseY - 12, SSD1306_WHITE);
display.drawLine(centerX, baseY - 6, centerX, baseY - 16, SSD1306_WHITE);
display.drawLine(centerX + 6, baseY - 4, centerX + 6, baseY - 12, SSD1306_WHITE);
}
void drawGameOver(const char* message) {
display.clearDisplay();
// Draw yellow status bar with game over message
display.fillRect(0, 0, SCREEN_WIDTH, YELLOW_BAR_HEIGHT, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
display.setTextSize(1);
display.setCursor(2, 0);
display.print("GAME OVER!");
display.setCursor(2, 8);
display.print(message);
// Draw relevant icon in blue area
if (strcmp(message, "Poop explosion!") == 0) {
drawStinkyPoop();
} else if (strcmp(message, "Starved!") == 0) {
// Draw a sad stick figure
int baseY = 32;
int centerX = SCREEN_WIDTH / 2;
display.drawCircle(centerX, baseY, 6, SSD1306_WHITE);
display.drawLine(centerX, baseY + 6, centerX, baseY + 24, SSD1306_WHITE);
display.drawLine(centerX, baseY + 10, centerX - 10, baseY + 18, SSD1306_WHITE);
display.drawLine(centerX, baseY + 10, centerX + 10, baseY + 18, SSD1306_WHITE);
display.drawLine(centerX, baseY + 24, centerX - 10, baseY + 40, SSD1306_WHITE);
display.drawLine(centerX, baseY + 24, centerX + 10, baseY + 40, SSD1306_WHITE);
// Sad mouth (simple frown)
display.drawLine(centerX - 3, baseY + 6, centerX + 3, baseY + 6, SSD1306_WHITE);
} else if (strcmp(message, "Overate! Exploded!") == 0) {
// Draw a stick figure with a big belly
int baseY = 32;
int centerX = SCREEN_WIDTH / 2;
display.drawCircle(centerX, baseY, 6, SSD1306_WHITE);
display.drawLine(centerX, baseY + 6, centerX, baseY + 24, SSD1306_WHITE);
display.drawLine(centerX, baseY + 10, centerX - 10, baseY + 18, SSD1306_WHITE);
display.drawLine(centerX, baseY + 10, centerX + 10, baseY + 18, SSD1306_WHITE);
display.drawLine(centerX, baseY + 24, centerX - 10, baseY + 40, SSD1306_WHITE);
display.drawLine(centerX, baseY + 24, centerX + 10, baseY + 40, SSD1306_WHITE);
// Big belly
display.drawCircle(centerX, baseY + 18, 8, SSD1306_WHITE);
} else if (strcmp(message, "Constipation!") == 0) {
// Draw a stick figure with a pained face
int baseY = 32;
int centerX = SCREEN_WIDTH / 2;
display.drawCircle(centerX, baseY, 6, SSD1306_WHITE);
display.drawLine(centerX, baseY + 6, centerX, baseY + 24, SSD1306_WHITE);
display.drawLine(centerX, baseY + 10, centerX - 10, baseY + 18, SSD1306_WHITE);
display.drawLine(centerX, baseY + 10, centerX + 10, baseY + 18, SSD1306_WHITE);
display.drawLine(centerX, baseY + 24, centerX - 10, baseY + 40, SSD1306_WHITE);
display.drawLine(centerX, baseY + 24, centerX + 10, baseY + 40, SSD1306_WHITE);
// Pained mouth (zigzag)
display.drawLine(centerX - 2, baseY + 5, centerX, baseY + 7, SSD1306_WHITE);
display.drawLine(centerX, baseY + 7, centerX + 2, baseY + 5, SSD1306_WHITE);
}
display.display();
}
void setup() {
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
while (true); // Don't proceed, loop forever
}
pinMode(FEED_BUTTON_PIN, INPUT_PULLUP);
pinMode(POOP_BUTTON_PIN, INPUT_PULLUP);
display.clearDisplay();
drawBars();
display.display();
lastUpdate = millis();
}
void loop() {
if (gameOver) return;
// Handle buttons (active LOW)
bool feedPressed = digitalRead(FEED_BUTTON_PIN) == LOW;
bool poopPressed = digitalRead(POOP_BUTTON_PIN) == LOW;
static bool lastFeedPressed = false;
static bool lastPoopPressed = false;
// Feed button: increase food, increase poop a bit
if (feedPressed && !lastFeedPressed) {
food += 15;
if (food > MAX_FOOD) food = MAX_FOOD;
poop += 5;
if (poop > MAX_POOP) poop = MAX_POOP;
}
// Poop button: decrease poop
if (poopPressed && !lastPoopPressed) {
poop -= 20;
if (poop < 0) poop = 0;
}
lastFeedPressed = feedPressed;
lastPoopPressed = poopPressed;
// Food decreases, poop increases over time
if (millis() - lastUpdate > updateInterval) {
lastUpdate = millis();
food--;
if (food < 0) food = 0;
if (food > 0) poop++;
if (poop > MAX_POOP) poop = MAX_POOP;
}
// Check game over conditions
if (food == 0) {
gameOver = true;
drawGameOver("Starved!");
return;
}
if (food == MAX_FOOD) {
gameOver = true;
drawGameOver("Overate! Exploded!");
return;
}
if (poop == MAX_POOP) {
gameOver = true;
drawGameOver("Poop explosion!");
return;
}
if (poop == 0) {
gameOver = true;
drawGameOver("Constipation!");
return;
}
// Redraw bars
display.clearDisplay();
drawBars();
// Animate stick figure in blue area
static int frame = 0;
drawStickFigure(frame);
frame = (frame + 1) % 2;
display.display();
delay(100);
}