Project tutorial
Snake LED Matrix Game

Snake LED Matrix Game © GPL3+

This is a fun classical snake game. And if you want you can put it in a frame to make it into a gaming console.

  • 3,238 views
  • 5 comments
  • 9 respects

Components and supplies

Rhxvhx2dhljmbtloxexc
Arduino Proto Shield
×1
A000066 iso both
Arduino UNO & Genuino UNO
×1
Analog joystick (Generic)
This is a normal black joystick
×1
826 04
Male/Female Jumper Wires
×1
13795 01
SparkFun LED Array - 8x7
This is just a normal 8 *8 LED matrix (not a RGB one)
×1

Apps and online services

About this project

I made a cool game console out of a Meccanoid and Erector set as the frame and I used Sergey Royz code (CHECK IT OUT) and I added extra stuff into it and increased the speed so it moved smoothly. I am not going to explain how to make the frame but I recommend you to make your own frame. But you do need a frame. Have fun with this do what you want. I HOPE THAT YOU LIKE THIS PROJECT! Comment if you have a question and I will hopefully be able to answer it as soon as possible and if you have any recommendations for my next project please comment and tell me. Also my fritzing was not working, so I will just tell you:

Schematics:

Attach the shield to the Arduino Uno so you have more GND and 5v outlets without using a breadboard.

Matrix:

  • VCC to 5V Arduino
  • GND to GND Arduino
  • DIN to digital pin 10 on Arduino
  • CS to digital pin 9 on Arduino
  • CLK to digital pin 8 on Arduino

Joystick:

  • Gnd to Gnd pin on Arduino
  • +5v to 5V on Arduino
  • VRX to A0 on Arduino
  • VRY to A1 on Arduino
  • SW to digital pin 2

Code

SnakeC/C++
All that you have to do is copy and paste the code
/**
 * Snake
 * Implementation of the classical Snake game 
 * where the snake moved constantly and the player
 * have to avoid intersections with itself and borders.
 * When the snake eats food it grows and speeds up a little bit.
 * 
 * 23 Jun 2016
 * by Sergey Royz and hunter Buzzell
 */

#include <LedControl.h>

/* Joystick PINs */
#define VRX     A0
#define VRY     A1
#define SW      2

/* Display PINs */
#define CLK     8
#define CS      9
#define DIN     10

#define SIZE    8
#define ADVANCE_DELAY 20


int snake[SIZE*SIZE][2];
int length;
int food[2], v[2];
bool is_game_over = false;
long current_time;
long prev_advance;
int blink_count;
const short messageSpeed = 5;



LedControl lc = LedControl(DIN, CLK, CS, 1);

void init_game() {
  prev_advance = current_time = 0;
  blink_count = 3;
  int half = SIZE / 2;
  length = SIZE / 3;

  for (int i = 0; i < length; i++) {
      snake[i][0] = half - 1;
      snake[i][1] = half + i;
  }

  food[0] = half + 1;
  food[1] = half - 1;

  v[0] = 0;
  v[1] = -1;
}

void render() {
  for (int i = 0; i < length; i++) {
    lc.setLed(0, snake[i][0], snake[i][1], 1);
  }
  lc.setLed(0, food[0], food[1], 1);
}

void clearScreen() {
  for (int x = 0; x < SIZE; x++) {
    for (int y = 0; y < SIZE; y++) {
      lc.setLed(0, x, y, 0);
    }
  }
}

/**
 * moves the snake forward
 * returns true if the game is over
 */
bool advance() {
  int head[2] = {snake[0][0] + v[0], snake[0][1] + v[1]};

  if (head[0] < 0 || head[0] >= SIZE) {

            delay(1000);
    showGameOverMessage();
      return true;
  }

  if (head[1] < 0 || head[1] >= SIZE) {

            delay(1000);
    showGameOverMessage();
      return true;
  }

  for (int i = 0; i < length; i++) {
      if (snake[i][0] == head[0] && snake[i][1] == head[1]) {
            delay(1000);
        showGameOverMessage();
          return true;
      }
  }

  bool grow = (head[0] == food[0] && head[1] == food[1]);
  if (grow) {
      length++;  
      randomSeed(current_time);    
      food[0] = random(SIZE);
      food[1] = random(SIZE);
  }

  for (int i = length - 1; i >= 0; i--) {
      snake[i + 1][0] = snake[i][0];
      snake[i + 1][1] = snake[i][1];
  }
  snake[0][0] += v[0];
  snake[0][1] += v[1];
  return false;
}

void setup() {
  pinMode(SW, INPUT_PULLUP);
  pinMode(VRX, INPUT);
  pinMode(VRY, INPUT);
  attachInterrupt(digitalPinToInterrupt(SW), restart, RISING);

  lc.shutdown(0, false);
  lc.setIntensity(0, 8);

  init_game();
  render();
}

void loop() {
  if (!is_game_over) {
    clearScreen();
    render();

    if (current_time - prev_advance > ADVANCE_DELAY) {
      is_game_over = advance();
      prev_advance = current_time;    
    }
  } else {
    while (blink_count > 0) {
      clearScreen();
      delay(300);
      render();
      delay(300);
      blink_count--;     
         
    }
  }
  readControls();
  current_time++;
}

void restart() {  
  init_game();
  is_game_over = false;
}

void readControls() {
  int dx = map(analogRead(VRX), 0, 906, 2, -2);
  int dy = map(analogRead(VRY), 0, 906, -2, 2);
  if (dx != 0) {dx = dx / abs(dx);}
  if (dy != 0) {dy = dy / abs(dy);}

  if (dy != 0 && v[0] != 0) {
    v[0] = 0;
    v[1] = dy;    
  }

  if (dx != 0 && v[1] != 0) {
    v[0] = dx;
    v[1] = 0;
  }

}

const PROGMEM bool gameOverMessage[8][90] = {
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,1,0,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,1,1,0,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}
}; 
void showGameOverMessage() {
  for (int d = 0; d < sizeof(gameOverMessage[0]) - 7; d++) {
    for (int col = 0; col < 8; col++) {
      delay(messageSpeed);
      for (int row = 0; row < 8; row++) {
        // this reads the byte from the PROGMEM and displays it on the screen
        lc.setLed(0, row, col, pgm_read_byte(&(gameOverMessage[row][col + d])));
      }
    }
  }
}

Comments

Similar projects you might like

8x8 Matrix LED Snake Game (Smartphone Motion)

Project tutorial by hmkim

  • 5,193 views
  • 2 comments
  • 19 respects

8X8 Matrix LED Snake Game (HTML5 Web Socket)

Project showcase by hmkim

  • 5,986 views
  • 1 comment
  • 16 respects

Arduino LED Matrix Game of Life

Project showcase by aerodynamics

  • 2,390 views
  • 0 comments
  • 15 respects

MAX72XX LED matrix display asteroids game

Project tutorial by kreck2003

  • 2,297 views
  • 3 comments
  • 16 respects

Analog Clock with LED Matrix and Arduino

Project tutorial by LAGSILVA

  • 12,237 views
  • 8 comments
  • 39 respects

Arduino Dot Matrix Game Console

Project tutorial by Md. Khairul Alam

  • 9,608 views
  • 1 comment
  • 30 respects
Add projectSign up / Login