#include <IRreceiver.h>
#include <DMD.h>
#include <Mono5x7.h>
#define SNAKE_ADVANCE_TIME 150
#define SNAKE_BLINK_TIME 500
#define SNAKE_INC_STEPS 5
#define SNAKE_MAX_LENGTH 50
#define SNAKE_START_LENGTH 10
struct Point
{
int x, y;
};
bool paused;
bool gameOver;
bool waitForStart;
bool snakeDrawn;
unsigned long lastChange;
Point direction;
Point snakeParts[SNAKE_MAX_LENGTH];
int snakeLength;
int incStep;
ISR(TIMER1_OVF_vect)
{
}
void setup() {
startGame();
}
for (int index = 0; index < snakeLength; ++index)
display.
setPixel(snakeParts[index].x, snakeParts[index].y, color);
}
void loop() {
if (gameOver) {
if (cmd != -1 && (cmd & IRreceiver::AUTO_REPEAT) == 0)
startGame();
return;
}
if (waitForStart) {
if (cmd == -1) {
if ((millis() - lastChange) >= SNAKE_BLINK_TIME) {
snakeDrawn = !snakeDrawn;
lastChange += SNAKE_BLINK_TIME;
}
return;
}
waitForStart = false;
snakeDrawn = true;
lastChange = millis();
}
switch (cmd) {
case RC5_LEFT: case RC5_4:
changeDirection(-1, 0);
break;
case RC5_RIGHT: case RC5_6:
changeDirection(1, 0);
break;
case RC5_UP: case RC5_2:
changeDirection(0, -1);
break;
case RC5_DOWN: case RC5_8:
changeDirection(0, 1);
break;
case RC5_PAUSE: case RC5_PLAY: case RC5_0:
paused = !paused;
lastChange = millis();
break;
case RC5_STOP: case RC5_STANDBY:
startGame();
break;
}
if (!paused && (millis() - lastChange) >= SNAKE_ADVANCE_TIME) {
++incStep;
advanceSnake(incStep >= SNAKE_INC_STEPS);
lastChange += SNAKE_ADVANCE_TIME;
}
}
void startGame() {
randomSeed(micros() + analogRead(A0));
for (int count = 0; count < 10; ++count) {
int x, y;
if (random(0, 2) == 0) {
x = random(1, display.
width() - 5);
y = random(1, display.
height() - 1);
} else {
x = random(1, display.
width() - 1);
y = random(1, display.
height() - 3);
}
}
paused = false;
gameOver = false;
waitForStart = true;
snakeDrawn = true;
lastChange = millis();
direction.x = 1;
direction.y = 0;
incStep = 0;
snakeLength = SNAKE_START_LENGTH;
for (int index = 0; index < snakeLength; ++index) {
snakeParts[index].x = 3 + index;
snakeParts[index].y = 4;
}
}
void changeDirection(int x, int y) {
direction.x = x;
direction.y = y;
}
void advanceSnake(bool increase) {
int x = snakeParts[snakeLength - 1].x + direction.x;
int y = snakeParts[snakeLength - 1].y + direction.y;
gameOver = true;
return;
}
if (!increase || snakeLength >= SNAKE_MAX_LENGTH) {
for (int index = 0; index < snakeLength - 1; ++index)
snakeParts[index] = snakeParts[index + 1];
} else {
++snakeLength;
}
snakeParts[snakeLength - 1].x = x;
snakeParts[snakeLength - 1].y = y;
if (increase)
incStep = 0;
}