#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SNAKE_PIECE_SIZE 3
#define MAX_SANKE_LENGTH 165
#define MAP_SIZE_X 20
#define MAP_SIZE_Y 20
#define STARTING_SNAKE_SIZE 5
#define SNAKE_MOVE_DELAY 30
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const byte buttonPins[] = {4, 2, 5, 3}; // LEFT, UP, RIGHT, DOWN
typedef enum {
START,
RUNNING,
GAMEOVER
} State;
typedef enum {
LEFT,
UP,
RIGHT,
DOWN
} Direction;
State gameState;
int8_t snake[MAX_SANKE_LENGTH][2];
uint8_t snake_length;
Direction dir;
Direction newDir;
int8_t fruit[2];
void setupGame() {
gameState = START;
dir = RIGHT;
newDir = RIGHT;
resetSnake();
generateFruit();
display.clearDisplay();
drawMap();
drawScore();
drawPressToStart();
display.display();
}
void setup() {
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
for (byte i = 0; i < 4; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
randomSeed(analogRead(A0));
setupGame();
}
int moveTime = 0;
void loop() {
switch(gameState) {
case START:
if(buttonPress()) gameState = RUNNING;
break;
case RUNNING:
moveTime++;
readDirection();
if(moveTime >= SNAKE_MOVE_DELAY) {
dir = newDir;
display.clearDisplay();
if(moveSnake()) {
gameState = GAMEOVER;
drawGameover();
delay(1000);
}
drawMap();
drawScore();
display.display();
checkFruit();
moveTime = 0;
}
break;
case GAMEOVER:
if(buttonPress()) {
delay(500);
setupGame();
gameState = START;
}
break;
}
delay(10);
display.display();
}
void displayTime() {
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("TIME:");
display.setCursor(15, 20);
display.print(currentTime.hours < 10 ? "0" : "");
display.print(currentTime.hours);
display.print(":");
display.print(currentTime.minutes < 10 ? "0" : "");
display.print(currentTime.minutes);
display.print(":");
display.print(currentTime.seconds < 10 ? "0" : "");
display.print(currentTime.seconds);
}
void checkButtons() {
// Implement button logic for setting time and alarm
if (btnB.wasPressed() || btnG.wasPressed())
{
setTime();
}
}
void setTime()
{
// Handle Hours
currentTime.seconds=0;
if(btnG.isPressed())
{
currentTime.hours++;
}
if (btnG.wasLongPressed() ) {
static unsigned long pm=cm;
if((cm-pm)>=200)
{
currentTime.hours++;
pm=cm;
}
}
if(currentTime.hours>23) currentTime.hours=0;
// Handle minutes
if(btnB.isPressed())
{
currentTime.minutes++;
}
if (btnB.wasLongPressed() ) {
static unsigned long pm=cm;
if((cm-pm)>=200)
{
currentTime.minutes++;
pm=cm;
}
}
if(currentTime.minutes>59) currentTime.minutes=0;
}
//ISR: Interrupt Service Routine:
void updateTime() {
if(!btnB.wasPressed()) currentTime.incrementSeconds();
}