#include #include // 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 = 1000; // 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); }