#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// Pins for the screen (SPI)
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
// Note: Connect Screen SDA -> 23, Screen SCL -> 18
// Button for jumping
#define JUMP_BUTTON 0
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Game Variables
int birdY, birdVy;
int pipeX, pipeGapY;
int score = 0;
bool isGameOver = true;
void setup() {
pinMode(JUMP_BUTTON, INPUT_PULLUP);
tft.begin();
tft.setRotation(0);
tft.fillScreen(ILI9341_CYAN);
resetGame();
}
void loop() {
// Check button press (LOW means pressed because of INPUT_PULLUP)
if (digitalRead(JUMP_BUTTON) == LOW) {
if (isGameOver) {
resetGame();
delay(500);
} else {
birdVy = -6; // Jump
}
}
if (!isGameOver) {
updateGame();
}
delay(20);
}
void resetGame() {
tft.fillScreen(ILI9341_CYAN);
birdY = 160;
birdVy = 0;
pipeX = 240;
pipeGapY = 100;
score = 0;
isGameOver = false;
}
void updateGame() {
// Erase old positions
tft.fillRect(50, birdY, 10, 10, ILI9341_CYAN);
tft.fillRect(pipeX+30-3, 0, 3, pipeGapY, ILI9341_CYAN);
tft.fillRect(pipeX+30-3, pipeGapY+80, 3, 320, ILI9341_CYAN);
// Update Physics
birdVy += 1; // Gravity
birdY += birdVy;
pipeX -= 3; // Pipe speed
// Reset Pipe
if (pipeX < -30) {
pipeX = 240;
pipeGapY = random(20, 200);
score++;
}
// Draw new positions
tft.fillRect(pipeX, 0, 30, pipeGapY, ILI9341_GREEN);
tft.fillRect(pipeX, pipeGapY+80, 30, 320, ILI9341_GREEN);
tft.fillRect(50, birdY, 10, 10, ILI9341_YELLOW);
// Collision
if (birdY < 0 || birdY > 310 || (50+10 > pipeX && 50 < pipeX+30 && (birdY < pipeGapY || birdY+10 > pipeGapY+80))) {
isGameOver = true;
tft.setCursor(50, 150);
tft.setTextColor(ILI9341_RED);
tft.setTextSize(3);
tft.print("GAME OVER");
}
}