#include <Adafruit_ILI9341.h>
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <Arduino.h>
// Pin definitions
#define TFT_CS 27
#define TFT_DC 26
#define TFT_RST 25
#define TFT_CLK 13
#define TFT_MISO 12
#define TFT_MOSI 14
#define TFT_LED 33
#define LEFT_BUTTON_PIN 22
#define RIGHT_BUTTON_PIN 23
// TFT screen dimensions
#define TFT_WIDTH 320
#define TFT_HEIGHT 240
// Runway properties
#define RUNWAY_WIDTH TFT_WIDTH / 3
#define RUNWAY_HEIGHT TFT_HEIGHT
// Player dimensions
#define PLAYER_WIDTH 20
#define PLAYER_HEIGHT 20
// Obstacle dimensions
#define OBSTACLE_WIDTH 20
#define OBSTACLE_HEIGHT 20
// Global variables
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST, TFT_CLK, TFT_MISO, TFT_MOSI);
int playerX;
int playerY;
int currentRunway = 0;
int lives = 3;
void setupTFT() {
tft.begin();
tft.setRotation(3);
tft.fillScreen(ILI9341_BLACK);
pinMode(TFT_LED, OUTPUT);
digitalWrite(TFT_LED, HIGH); // Turn on the backlight
}
void clearObstacle(int x, int y) {
tft.fillRect(x, y, OBSTACLE_WIDTH, OBSTACLE_HEIGHT, ILI9341_BLACK);
}
void setupPlayer() {
playerX = (RUNWAY_WIDTH - PLAYER_WIDTH) / 2;
playerY = TFT_HEIGHT - PLAYER_HEIGHT;
tft.fillRect(playerX, playerY, PLAYER_WIDTH, PLAYER_HEIGHT, ILI9341_YELLOW);
}
void updatePlayerPosition() {
if (digitalRead(LEFT_BUTTON_PIN) == LOW) {
currentRunway = (currentRunway + 2) % 3;
}
if (digitalRead(RIGHT_BUTTON_PIN) == LOW) {
currentRunway = (currentRunway + 1) % 3;
}
tft.fillRect(playerX, playerY, PLAYER_WIDTH, PLAYER_HEIGHT, ILI9341_BLACK);
playerX = currentRunway * RUNWAY_WIDTH + (RUNWAY_WIDTH - PLAYER_WIDTH) / 2;
tft.fillRect(playerX, playerY, PLAYER_WIDTH, PLAYER_HEIGHT, ILI9341_YELLOW);
}
void drawObstacle(int x, int y) {
tft.fillRect(x, y, OBSTACLE_WIDTH, OBSTACLE_HEIGHT, ILI9341_RED);
}
bool checkCollision(int obstacleX, int obstacleY) {
if (playerX + PLAYER_WIDTH >= obstacleX && playerX <= obstacleX + OBSTACLE_WIDTH &&
playerY + PLAYER_HEIGHT >= obstacleY && playerY <= obstacleY + OBSTACLE_HEIGHT) {
return true;
}
return false;
}
void gameOver() {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(TFT_WIDTH / 2 - 50, TFT_HEIGHT / 2 - 10);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(3);
tft.println("Game Over");
while (true) {
// Endless loop to keep the "Game Over" message on the screen
}
}
void setup() {
Serial.begin(115200);
pinMode(LEFT_BUTTON_PIN, INPUT_PULLUP);
pinMode(RIGHT_BUTTON_PIN, INPUT_PULLUP);
setupTFT();
setupPlayer();
pinMode(TFT_LED, OUTPUT);
digitalWrite(TFT_LED, HIGH); // Turn on the backlight
}
void loop() {
updatePlayerPosition();
int obstacleX = random(currentRunway * RUNWAY_WIDTH, (currentRunway + 1) * RUNWAY_WIDTH - OBSTACLE_WIDTH);
int obstacleY = 0;
drawObstacle(obstacleX, obstacleY);
while (obstacleY < TFT_HEIGHT) {
if (checkCollision(obstacleX, obstacleY)) {
lives--;
if (lives == 0) {
gameOver();
}
}
obstacleY++;
clearObstacle(obstacleX, obstacleY - OBSTACLE_HEIGHT);
drawObstacle(obstacleX, obstacleY);
delay(100);
}
}