Created
December 16, 2013 22:48
-
-
Save stefreak/7995953 to your computer and use it in GitHub Desktop.
arduino fritzing led matrix snake
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define X 1 | |
#define Y 0 | |
#define GAMESTATE_NORMAL 0 | |
#define GAMESTATE_GAMEOVER 1 | |
int soundPin = 4; | |
int rowPins[8] = { | |
9,22,18,12,15,11,7,6}; // matrix rows connected to the Arduino | |
int colPins[8] = { | |
13,8,17,10,5,16,19,14}; // matrix columns connected to the Arduino | |
int image[8][8]={ // the image displayed on the matrix : 1 = LED on, 0 = LED off | |
{ | |
1,1,1,1,1,1,1,1 } | |
, | |
{ | |
1,1,1,1,1,1,1,1 } | |
, | |
{ | |
1,1,1,1,1,1,1,1 } | |
, | |
{ | |
1,1,1,1,1,1,1,1 } | |
, | |
{ | |
1,1,1,1,1,1,1,1 } | |
, | |
{ | |
1,1,1,1,1,1,1,1 } | |
, | |
{ | |
1,1,1,1,1,1,1,1 } | |
, | |
{ | |
1,1,1,1,1,1,1,1 } | |
}; | |
#define BUTTON_LEFT 1 | |
#define BUTTON_RIGHT 2 | |
int leftPin = 2; | |
int rightPin = 3; | |
int buttonStackLength = 0; | |
int buttonStack[10] = { | |
0,0,0,0,0,0,0,0,0,0}; | |
void pushButton(int button) { | |
buttonStack[buttonStackLength++] = button; | |
} | |
int getNextButton() { | |
if (buttonStackLength > 0) { | |
int nextButton = buttonStack[0]; | |
memmove(&buttonStack[0], &buttonStack[1], sizeof(buttonStack) - sizeof(*buttonStack)); | |
buttonStackLength --; | |
return nextButton; | |
} | |
return 0; | |
} | |
int gameState = GAMESTATE_NORMAL; | |
int snakeLength = 3; | |
int snake[100][2]={ | |
{ | |
0,0 } | |
, { | |
1,0 } | |
, { | |
2,0 } | |
}; | |
int snakeDirection[2] = { | |
1, 0}; | |
int foodInvalid = 1; | |
int food[2] = { | |
0, 0}; | |
int speedMultiplier = 40; | |
void setup(){ | |
for (int i=0; i<8; i++){ // all pins are declared as outputs | |
pinMode(rowPins[i],OUTPUT); | |
pinMode(colPins[i],OUTPUT); | |
} | |
pinMode(soundPin, OUTPUT); | |
pinMode(leftPin, INPUT); | |
pinMode(rightPin, INPUT); | |
fill(0); | |
gameState = GAMESTATE_NORMAL; | |
speedMultiplier = 40; | |
Serial.begin(9600); | |
} | |
unsigned long counter = 0; | |
void loop(){ | |
if (gameState == GAMESTATE_GAMEOVER) { | |
fill(1); | |
render(); | |
tone(soundPin, 120, 100); | |
if (! (counter++ % (500))) { | |
software_Reset() ; | |
} | |
return; | |
} | |
readButtonStates(); | |
if (! (counter++ % (10000/speedMultiplier))) { | |
tick(); | |
} | |
render(); | |
} | |
int tickCount = 0; | |
void tick() { | |
fill(0); | |
makeFood(); | |
int nextButton = getNextButton(); | |
if (nextButton == BUTTON_LEFT) { | |
turnLeft(); | |
} | |
if (nextButton == BUTTON_RIGHT) { | |
turnRight(); | |
} | |
moveSnake(); | |
// blit | |
image[food[X]][food[Y]] = 1; | |
for (int i=0; i<snakeLength; i++) { | |
image[snake[i][X]][snake[i][Y]] = 1; | |
} | |
} | |
int lastLeftState = -1; | |
int lastRightState = -1; | |
void readButtonStates() { | |
int leftState = digitalRead(leftPin); | |
int rightState = digitalRead(rightPin); | |
if (lastLeftState != leftState) { | |
if (leftState == LOW) { | |
//Serial.println("LEFT: %i"); | |
pushButton(BUTTON_LEFT); | |
} | |
} | |
if (lastRightState != rightState) { | |
if (rightState == LOW) { | |
pushButton(BUTTON_RIGHT); | |
} | |
} | |
lastLeftState = leftState; | |
lastRightState = rightState; | |
} | |
void moveSnake() { | |
if (snake[snakeLength-1][Y] + snakeDirection[Y] == food[Y] && snake[snakeLength-1][X] + snakeDirection[X] == food[X]) { | |
tone(soundPin, 261, 100); | |
snake[snakeLength][X] = food[X]; | |
snake[snakeLength][Y] = food[Y]; | |
snakeLength+=1; | |
foodInvalid = 1; | |
//speedMultiplier += 5; | |
return; | |
} | |
memmove(&snake[0], &snake[1], sizeof(snake) - sizeof(*snake)); | |
if (snakeHitCoordinates(snake[snakeLength-2][X] + snakeDirection[X], snake[snakeLength-2][Y] + snakeDirection[Y])) { | |
gameState = GAMESTATE_GAMEOVER; | |
counter = 1; | |
} | |
snake[snakeLength-1][X] = snake[snakeLength-2][X] + snakeDirection[X]; | |
snake[snakeLength-1][Y] = snake[snakeLength-2][Y] + snakeDirection[Y]; | |
if(snake[snakeLength-1][Y] < 0 || snake[snakeLength-1][Y] > 7 || snake[snakeLength-1][X] < 0 || snake[snakeLength-1][X] > 7) { | |
gameState = GAMESTATE_GAMEOVER; | |
counter = 1; | |
} | |
} | |
void turnRight() { | |
if (snakeDirection[X] == 1 && snakeDirection[Y] == 0) { | |
snakeDirection[X] = 0; | |
snakeDirection[Y] = -1; | |
} | |
else if (snakeDirection[X] == 0 && snakeDirection[Y] == 1) { | |
snakeDirection[X] = 1; | |
snakeDirection[Y] = 0; | |
} | |
else if (snakeDirection[X] == -1 && snakeDirection[Y] == 0) { | |
snakeDirection[X] = 0; | |
snakeDirection[Y] = 1; | |
} | |
else if (snakeDirection[X] == 0 && snakeDirection[Y] == -1) { | |
snakeDirection[X] = -1; | |
snakeDirection[Y] = 0; | |
} | |
} | |
void turnLeft() { | |
if (snakeDirection[X] == 1 && snakeDirection[Y] == 0) { | |
snakeDirection[X] = 0; | |
snakeDirection[Y] = 1; | |
} | |
else if (snakeDirection[X] == 0 && snakeDirection[Y] == 1) { | |
snakeDirection[X] = -1; | |
snakeDirection[Y] = 0; | |
} | |
else if (snakeDirection[X] == -1 && snakeDirection[Y] == 0) { | |
snakeDirection[X] = 0; | |
snakeDirection[Y] = -1; | |
} | |
else if (snakeDirection[X] == 0 && snakeDirection[Y] == -1) { | |
snakeDirection[X] = 1; | |
snakeDirection[Y] = 0; | |
} | |
} | |
void makeFood() { | |
if (foodInvalid) { | |
foodInvalid = 0; | |
do { | |
food[X] = random(0, 7); | |
food[Y] = random(0, 7); | |
} | |
while (snakeHitCoordinates(food[X], food[Y])); | |
} | |
} | |
bool snakeHitCoordinates(int Xcoord, int Ycoord) { | |
for (int i=0; i<snakeLength; i++) { | |
if (snake[i][X] == Xcoord && snake[i][Y] == Ycoord) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
void fill(int i) { | |
for (int y=0; y<8; y++){ | |
for (int x=0; x<8; x++){ | |
image[x][y] = i; | |
} | |
} | |
} | |
void render() { | |
for (int y=0; y<8; y++){ // rowwise | |
for (int x=0; x<8; x++){ // check all entries of the array from left to right | |
if (image[x][y]==1){ // is the entry 1 | |
digitalWrite(colPins[x],HIGH); // switch on column pin | |
} | |
else { // else | |
digitalWrite(colPins[x],LOW); // switch it off | |
} | |
} | |
digitalWrite(rowPins[y],LOW); // switch the row pin to LOW (because it is the cathode of the LED; LOW means ON) | |
delayMicroseconds(100); // stop the program for 100 milliseconds | |
digitalWrite(rowPins[y],HIGH); // switch the row pin to HIGH (this means OFF) | |
} | |
} | |
void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers | |
{ | |
asm volatile (" jmp 0"); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment