#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Controls
#define BTN_LEFT 2
#define BTN_RIGHT 3
// Bin settings
int binX = 54;
const int binWidth = 20;
const int binY = SCREEN_HEIGHT - 8;
// Trash settings
int trashX;
int trashY = 0;
bool trashActive = true;
// Game state
int score = 0;
bool gameRunning = true;
// Button press counters for acceleration
int leftPressCount = 0;
int rightPressCount = 0;
void setup() {
pinMode(BTN_LEFT, INPUT_PULLUP);
pinMode(BTN_RIGHT, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
randomSeed(analogRead(0));
spawnTrash();
}
void loop() {
if (gameRunning) {
// Accelerated bin movement
if (digitalRead(BTN_LEFT) == LOW) {
leftPressCount++;
int moveStep = min(1 + leftPressCount / 5, 5); // up to 5 pixels per loop
if (binX > 0) binX -= moveStep;
} else {
leftPressCount = 0;
}
if (digitalRead(BTN_RIGHT) == LOW) {
rightPressCount++;
int moveStep = min(1 + rightPressCount / 5, 5); // up to 5 pixels per loop
if (binX < SCREEN_WIDTH - binWidth) binX += moveStep;
} else {
rightPressCount = 0;
}
// Move trash down
if (trashActive) {
trashY += 2;
// Check for catch or miss
if (trashY >= binY - 2 && trashY <= binY + 4) {
if (trashX + 5 >= binX && trashX <= binX + binWidth) {
score++;
spawnTrash();
} else if (trashY >= SCREEN_HEIGHT) {
gameRunning = false;
showGameOver();
}
}
if (trashY >= SCREEN_HEIGHT) {
gameRunning = false;
showGameOver();
}
}
// Draw screen
display.clearDisplay();
// Trash
display.fillRect(trashX, trashY, 5, 5, SSD1306_WHITE);
// Bin
display.fillRect(binX, binY, binWidth, 6, SSD1306_WHITE);
// Score
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Score: ");
display.print(score);
display.display();
delay(50);
} else {
// Game over - wait for button press to restart
if (digitalRead(BTN_LEFT) == LOW || digitalRead(BTN_RIGHT) == LOW) {
resetGame();
}
delay(100);
}
}
void spawnTrash() {
trashX = random(0, SCREEN_WIDTH - 5);
trashY = 0;
trashActive = true;
}
void showGameOver() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(10, 20);
display.println("Game Over");
display.setTextSize(1);
display.setCursor(30, 45);
display.print("Score: ");
display.print(score);
display.setCursor(10, 56);
display.print("Press button to restart");
display.display();
}
void resetGame() {
binX = 54;
score = 0;
trashY = 0;
trashActive = true;
gameRunning = true;
leftPressCount = 0;
rightPressCount = 0;
spawnTrash();
display.clearDisplay();
}