#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
#define VRX A0
#define VRY A1
#define SW 2
#define CELL 4
#define MAX_X (SCREEN_WIDTH / CELL)
#define MAX_Y (SCREEN_HEIGHT / CELL)
#define MAX_SNAKE 120
int snakeX[MAX_SNAKE];
int snakeY[MAX_SNAKE];
int len = 5;
int dirX = 1;
int dirY = 0;
int foodX, foodY;
void spawnFood() {
foodX = random(0, MAX_X);
foodY = random(0, MAX_Y);
}
void resetGame() {
len = 5;
dirX = 1;
dirY = 0;
for (int i = 0; i < len; i++) {
snakeX[i] = 10 - i;
snakeY[i] = 10;
}
spawnFood();
}
void setup() {
pinMode(VRX, INPUT);
pinMode(VRY, INPUT);
pinMode(SW, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
randomSeed(analogRead(A3));
resetGame();
}
void loop() {
readJoystick();
if (digitalRead(SW) == LOW) resetGame();
moveSnake();
checkGame();
draw();
delay(120);
}
void readJoystick() {
int x = analogRead(VRX);
int y = analogRead(VRY);
y = 1023 - y;
x = 1023 - x;
if (x < 350 && dirX != 1) { dirX = -1; dirY = 0; }
else if (x > 700 && dirX != -1) { dirX = 1; dirY = 0; }
if (y < 350 && dirY != 1) { dirX = 0; dirY = -1; }
else if (y > 700 && dirY != -1) { dirX = 0; dirY = 1; }
}
void moveSnake() {
for (int i = len; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
snakeX[0] += dirX;
snakeY[0] += dirY;
}
void checkGame() {
if (snakeX[0] < 0 || snakeX[0] >= MAX_X ||
snakeY[0] < 0 || snakeY[0] >= MAX_Y) {
resetGame();
}
for (int i = 1; i < len; i++) {
if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
resetGame();
}
}
if (snakeX[0] == foodX && snakeY[0] == foodY) {
if (len < MAX_SNAKE - 1) len++;
spawnFood();
}
}
void draw() {
display.clearDisplay();
display.fillRect(foodX * CELL, foodY * CELL, CELL, CELL, WHITE);
for (int i = 0; i < len; i++) {
display.fillRect(snakeX[i] * CELL, snakeY[i] * CELL, CELL, CELL, WHITE);
}
display.display();
}