#include <Adafruit_GFX.h>
#include <Adafruit_HX8357.h>
#include <Wire.h>
// Define the screen
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);
#define JOY_X A0
#define JOY_Y A1
// Snake variables
#define SNAKE_SIZE 10
int snakeX[SNAKE_SIZE], snakeY[SNAKE_SIZE];
int snakeLength = 1;
int direction = 0; // 0: right, 1: up, 2: left, 3: down
// Food variables
int foodX, foodY;
void setup() {
Serial.begin(9600);
// Initialize screen
tft.begin();
tft.setRotation(1);
// Initialize snake
snakeX[0] = tft.width() / 2;
snakeY[0] = tft.height() / 4;
// Initialize food
spawnFood();
// Draw initial state
drawSnake();
drawFood();
}
void loop() {
// Update joystick and move snake
updateJoystick();
moveSnake();
// Check for collisions
if (checkCollision()) {
gameOver();
}
// Check if snake eats food
if (snakeX[0] == foodX && snakeY[0] == foodY) {
snakeLength++;
spawnFood();
}
// Draw updated state
drawSnake();
drawFood();
delay(100);
}
void updateJoystick() {
// Read joystick values
int joyX = analogRead(JOY_X);
int joyY = analogRead(JOY_Y);
// Update direction based on joystick input
if (joyX < 300 && abs(joyX - 512) > 50) {
direction = 2; // Left
} else if (joyX > 700 && abs(joyX - 512) > 50) {
direction = 0; // Right
}
if (joyY < 300 && abs(joyY - 512) > 50) {
direction = 1; // Up
} else if (joyY > 700 && abs(joyY - 512) > 50) {
direction = 3; // Down
}
}
void moveSnake() {
// Move the body of the snake
for (int i = snakeLength - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
// Move the head of the snake
switch (direction) {
case 0: // Right
snakeX[0] += 10;
break;
case 1: // Up
snakeY[0] -= 10;
break;
case 2: // Left
snakeX[0] -= 10;
break;
case 3: // Down
snakeY[0] += 10;
break;
}
}
void drawSnake() {
tft.fillScreen(HX8357_BLACK);
// Draw each segment of the snake
for (int i = 0; i < snakeLength; i++) {
tft.fillRect(snakeX[i], snakeY[i], 10, 10, HX8357_BLUE);
}
}
void drawFood() {
// Draw the food
tft.fillRect(foodX, foodY, 10, 10, HX8357_WHITE);
}
void spawnFood() {
// Generate random coordinates for food
foodX = random(0, tft.width() / 10) * 10;
foodY = random(0, tft.height() / 10) * 10;
}
bool checkCollision() {
// Check if the snake collides with the screen edges
if (snakeX[0] < 0 || snakeX[0] >= tft.width() || snakeY[0] < 0 || snakeY[0] >= tft.height()) {
return true;
}
// Check if the snake collides with itself
for (int i = 1; i < snakeLength; i++) {
if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
return true;
}
}
return false;
}
void gameOver() {
// Game over message
tft.setCursor(tft.width() / 4, tft.height() / 2);
tft.setTextColor(HX8357_WHITE);
tft.setTextSize(2);
tft.print("Game Over!");
while (1);
}