Skip to content

Instantly share code, notes, and snippets.

@annappropriate
Created April 3, 2015 10:04
Show Gist options
  • Save annappropriate/74fc35fad84a29ffadbf to your computer and use it in GitHub Desktop.
Save annappropriate/74fc35fad84a29ffadbf to your computer and use it in GitHub Desktop.
LED matrix + Joystick snake game
#include <LedControl.h>
// Display
int din = 8;
int clk = 10;
int cs = 9;
// Joystick click
int sw = 5;
// Joystick move
int x = 3;
int y = 4;
int tilt_max = 700;
int tilt_min = 300;
LedControl matrix(din, clk, cs);
int food_x;
int food_y;
int head_last_x;
int head_last_y;
int width = 8;
boolean needNewFood = true;
int max_body_length = 20; // WTF?
int head = 0;
int tail = 0;
int body_xs[20];
int body_ys[20];
boolean gameOver = false;
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
start();
}
void loop() {
if (!gameOver) {
head_last_x = body_xs[head];
head_last_y = body_ys[head];
moveJoystick();
// Move head
ledOn(body_xs[head], body_ys[head]);
delay(100);
// Generate new food
if (needNewFood) {
newFood();
}
if (headAndFoodCollide()) {
Serial.println("Om-nom-nom");
growSnake();
needNewFood = true;
}
if(headCollidesWithBody()) {
Serial.println("Collision!");
gameOver = true;
}
}
else {
for (int i = 0; i < width; i++) {
matrix.setRow(0, i, B11111111);
delay(500);
}
// matrix.shutdown(0, false);
if(digitalRead(sw) == 0) {
Serial.println("Reset");
gameOver = false;
for (int i = 0; i < width; i++) {
matrix.setRow(0, i, B00000000);
delay(500);
}
start();
}
}
}
void start() {
matrix.shutdown(0, false);
matrix.setIntensity(0, 2); // 0-16
head = 0;
tail = 0;
food_x = 0;
food_y = 0;
head_last_x = 0;
head_last_y = 0;
needNewFood = true;
randomStart();
}
void moveJoystick() {
// Movements
if (body_xs[head] < 7 && analogRead(x) > tilt_max) {
moveSnake();
body_xs[head]++;
}
else if (body_xs[head] > 0 && analogRead(x) < tilt_min) {
moveSnake();
body_xs[head]--;
}
else if (body_ys[head] < 7 && analogRead(y) < tilt_min) {
moveSnake();
body_ys[head]++;
}
else if (body_ys[head] > 0 && analogRead(y) > tilt_max) {
moveSnake();
body_ys[head]--;
}
}
void newFood() {
do {
food_x = random(width);
food_y = random(width);
}
while (bodyAndFoodCollide());
Serial.print("New food at (");
Serial.print(food_x + 1);
Serial.print(", ");
Serial.print(food_y + 1);
Serial.print(")");
Serial.println();
needNewFood = false;
ledOn(food_x, food_y);
}
boolean headAndFoodCollide() {
if(food_x == body_xs[head] && food_y == body_ys[head]) {
// Reset values to prevent multiple loop events
food_x = -1;
food_y = -1;
return true;
}
return false;
}
boolean bodyAndFoodCollide() {
for (int i = 0; i <= tail; i++) {
if(food_x == body_xs[i] && food_y == body_ys[i]) {
// Reset values to prevent multiple loop events
food_x = -1;
food_y = -1;
return true;
}
return false;
}
}
boolean headCollidesWithBody() {
for (int i = 1; i <= tail; i++) {
if (body_xs[head] == body_xs[i] && body_ys[head] == body_ys[i]) {
return true;
}
}
return false;
}
void moveSnake() {
ledOff(body_xs[tail], body_ys[tail]);
shiftArray();
}
void growSnake() {
tail++;
shiftArray();
body_xs[1] = head_last_x;
body_ys[1] = head_last_y;
}
void shiftArray() {
for (int i = tail; i > 0; i--) {
body_xs[i] = body_xs[i - 1];
body_ys[i] = body_ys[i - 1];
}
}
void printSnake() {
Serial.println("Snake:");
for (int i = 0; i <= tail; i++) {
Serial.print("(");
Serial.print(body_xs[i] + 1);
Serial.print(", ");
Serial.print(body_ys[i] + 1);
Serial.println(")");
}
}
void ledOn(int x, int y) {
matrix.setLed(0, x, y, true);
}
void ledOff(int x, int y) {
matrix.setLed(0, x, y, false);
}
void ledOnDebug(int x, int y) {
Serial.print("Led ");
Serial.print("(");
Serial.print(x + 1);
Serial.print(", ");
Serial.print(y + 1);
Serial.print(")");
Serial.println(" set ON");
matrix.setLed(0, x, y, true);
}
void ledOffDebug(int x, int y) {
Serial.print("Led ");
Serial.print("(");
Serial.print(x + 1);
Serial.print(", ");
Serial.print(y + 1);
Serial.print(")");
Serial.println(" set OFF");
matrix.setLed(0, x, y, false);
}
void randomStart() {
// Start from a random cell
body_xs[head] = random(width);
body_ys[head] = random(width);
ledOn(body_xs[head], body_ys[head]);
Serial.print("Starting at (");
Serial.print(body_xs[head] + 1);
Serial.print(", ");
Serial.print(body_ys[head] + 1);
Serial.print(")");
Serial.println();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment