# NeoPixels Matrix：Snake Game

1,758

2

1

## Introduction: NeoPixels Matrix：Snake Game

Do you still remember snake game we played on our game box or mobile during our childhood? Today we are going to learn how to make a snake game with 8*8 NeoPixels Matrix. We choose Arduino uno as the control center and Joystick breakout module to control the snake.

Hardware:

3 X Guide Line

Software:

Arduino IDE

## Step 2: Hardware Connection

Connect NeoPixels to pin D2.

"X" on Joystick breakout module connect pin A0 on Arduino UNO board, "Y" connect pin A1, "K" connect pin A2.

## Step 3: Programming

```<span style="color: black; font-family: Arial; font-size: 12pt;">P#include <Adafruit_NeoPixel.h>

#define PIN 2           //Output Pin
#define MAX_LED 64       //Quantity of bead
uint32_t c;
int a = 0 , number;
unsigned char huan = 0, ci = 0;
unsigned char  u = 40; //The font size of word group
unsigned char x = 0;
unsigned char Colour[3];
unsigned char go[] = {2, 3, 4, 5, 9, 14, 17, 20, 22, 26, 27, 29, 34, 35, 36, 37, 41, 46, 49, 54, 58, 59, 60, 61}; //24
unsigned char light[8][8] = {
{0, 1, 2, 3, 4, 5, 6, 7},
{15, 14, 13, 12, 11, 10, 9, 8},
{16, 17, 18, 19, 20, 21, 22, 23},
{31, 30, 29, 28, 27, 26, 25, 24},
{32, 33, 34, 35, 36, 37, 38, 39},
{47, 46, 45, 44, 43, 42, 41, 40},
{48, 49, 50, 51, 52, 53, 54, 55},
{63, 62, 61, 60, 59, 58, 57, 56},
} ;
unsigned char character[][8] =  //Set the word to be sent
{
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 0, 0, 0, 1, 0, 0}, // 0
{0, 1, 1, 1, 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, 0, 0}, // 1
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},

{0, 1, 0, 1, 1, 1, 0, 0},
{0, 1, 0, 1, 0, 1, 0, 0}, // 2
{0, 1, 1, 1, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},

{0, 1, 0, 1, 0, 1, 0, 0},
{0, 1, 0, 1, 0, 1, 0, 0}, // 3
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},

{0, 1, 1, 1, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0}, // 4
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},

{0, 1, 1, 1, 0, 1, 0, 0},
{0, 1, 0, 1, 0, 1, 0, 0}, // 5
{0, 1, 0, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},

{0, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 0, 1, 0, 1, 0, 0}, // 6
{0, 1, 0, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},

{0, 1, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0}, // 7
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},

{0, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 0, 1, 0, 1, 0, 0}, // 8
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},

{0, 1, 1, 1, 0, 1, 0, 0},
{0, 1, 0, 1, 0, 1, 0, 0}, // 9
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
};

unsigned char displayscore [8][8];

int speedS = 400;                                                         // Initial speed of snake
int score;                                                              // Game score
int xValue;                                                             // JoyStick-X
int yValue;                                                             // JoyStick-Y
int zValue;                                                             // JoyStick-Z
int FX, FY;                                                             // Coordinate of food
int SX, SY;                                                             // Coordinate of snake head
int KEY, K;
int Enabled;                                                            // Enable to restart game

char sx[64] ;                                                     //Coordinate of snake body
char sy[64];

void RANDOM() {
A:
FX = random(0, 7);
FY = random(0, 7);

for (int i = 0; i < 3 + score; i++)          //Prevent food display on snake body
{
if ( FX == sx[i] && FY == sy[i])
goto A;
}
}
void myDelay( unsigned int Time) {                             // During the delay period of snake movement, we have to do something like food glitter and read the direction of Joystick

for (int t = 1; t <= Time; t++)
{
joyStick();
delay(1);                                     //Read the direction of Joystick
}
}
void joyStick() {

xValue = analogRead(A0);                             // JoyStick-X   The leftmost value is 0, the rightmost value is 1023, and the middle value is 515.
yValue = analogRead(A1);                             // JoyStick-Y   The bottom value is 0, the top value is 1023, the middle value is 510.

if (yValue > 950 && KEY != 5) {
K = 8;
}
else if (yValue < 50 && KEY != 8) {
K = 5;
}
else if (xValue < 50  && KEY != 6 && K != 0) {       // Before operate Joystic for the first time, you can't move snake to the left direction.
K = 4;
}
else if (xValue > 950 && KEY != 4) {
K = 6;
}
}
// Here you can compare whether the direction of keypad is opposite to the snake move direction. If it is opposite, then give up the keypad.
/***************************************************************************************************************************************************************************************************************/
void gameover() {                                      // Once Gameover program stopped, press the central button to restart the game.
unsigned char value, y;

Colour[0] = random(3 , 18); // Set color.Parameter is R G B, range 0-255.
Colour[1] = random(3, 18);
Colour[2] = random(3, 18);
c = strip.Color(Colour[1], Colour[0], Colour[2]);
value = score / 10;
value = value * 4;
y = 0;

for (number = value; number < value + 4; number++)
{
for (unsigned char vertical = 0; vertical < 8; vertical++)
{
displayscore[y][vertical] = character[number][vertical];

}
y++;
}

value = score % 10;
value = value * 4;

for (number = value; number < value + 4; number++)
{
for (unsigned char vertical = 0; vertical < 8; vertical++)
{
displayscore[y][vertical] = character[number][vertical];

}
y++;
}

for (unsigned char horizontal = 0; horizontal < 8; horizontal++)
{
for (unsigned char vertical = 0; vertical < 8; vertical++)
{

if (displayscore[horizontal][vertical] == 1) //Judge whether the light is on.
{
strip.setPixelColor(light[horizontal][vertical],  c);
}
else
strip.setPixelColor(light[horizontal][vertical],  0);

}
}

strip.show();//Send data
delay(5000);
K = 0;                  // Reset Joystick direction
sx[0] = 2;
sx[1] = 1;
sx[2] = 0;
sy[0] = 1;
sy[1] = 1;
sy[2] = 1;               // Reset snake coordinate
score = 0;              // Reset game score
speedS = 400;                                                         // The initial speed of snake

}
void setup() {
Serial.begin(9600);
// Initialize library
strip.begin();
// Send data. Default the color of each point as 0. So every point is not illuminated at the beginning.
strip.show();
K = 0;                  // Reset the direction of Joystick
sx[0] = 2;
sx[1] = 1;
sx[2] = 0;
sy[0] = 1;
sy[1] = 1;
sy[2] = 1;               // Reset snake coordinate
score = 0;              // Reset game score
Colour[0] = random(3 , 18); // Set color.Parameter is R G B, range 0-255.
Colour[1] = random(3, 18);
Colour[2] = random(3, 18);
c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green  Red Blue // Set color
for (number = 0; number < 24; number++)
{
strip.setPixelColor(go[number],  c);
}
strip.show();// Send data
delay(2000);
RANDOM();     //Produce food
}
void mobile()
{

KEY = K;                                      //Every movement of snake makes the direction change for once.

if (KEY == 8)                                 // Snake upward movement
{
for (int i = 2 +  score; i > 0; i--)
{
sx[i] = sx[i - 1];
sy[i] = sy[i - 1];
}
sy[0] = sy[0] - 1;
if (sy[0] < 0)                               // Go beyond the border and continue on the other side
sy[0] = 7;
}
else if (KEY == 5)                            // Snake downward movement
{
for (int i = 2 +  score; i > 0; i--)
{
sx[i] = sx[i - 1];
sy[i] = sy[i - 1];
}
sy[0] = sy[0] + 1;
if (sy[0] > 7)                               // Go beyond the border and continue on the other side
sy[0] = 0;
}
else if (KEY == 4)                            // Snake left movement
{
for (int i = 2 +  score; i > 0; i--)
{
sx[i] = sx[i - 1];
sy[i] = sy[i - 1];
}
sx[0] = sx[0] - 1;
if (sx[0] < 0)                               // Go beyond the border and continue on the other side
sx[0] = 7;
}
else if (KEY == 6)                            // Snake right movement
{
for (int i = 2 +  score; i > 0; i--)
{
sx[i] = sx[i - 1];
sy[i] = sy[i - 1];
}
sx[0] = sx[0] + 1;
if (sx[0] > 7)                               // Go beyond the border and continue on the other side
sx[0] = 0;
}
// Move snake body with button
}
void displays()
{
for (number = 0; number < 64; number++)   //Clear the screen
{
strip.setPixelColor(number,  0);
}
strip.show();

Colour[0] = 40; // Set color. Parameter is R G B, range 0-255.
Colour[1] = 0;
Colour[2] = 0;
c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue    // Set color
x = light[FX][FY];                                              //Display food
strip.setPixelColor(x, c);

Colour[0] = random(3 , 18); // Set color. Parameter is R G B, range 0-255.
Colour[1] = random(3, 18);
Colour[2] = random(3, 18);
c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue  // Set color

for (int i = 2 +  score; i > 0; i--)                   //Display snake body
{

x = light[sx[i]][sy[i]];
strip.setPixelColor(x,  c);
}

Colour[0] = 0; // Set color. Parameter is R G B, range 0-255.
Colour[1] = 40;
Colour[2] = 0;
c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue    // Set color
x = light[sx[0]][sy[0]];                                        //Display snake head
strip.setPixelColor(x,  c);

strip.show();//Send data
}
void loop() {

mobile();
myDelay(speedS);                                // Within（) is delay time.
displays();
SX = sx[0];
SY = sy[0];
// Get coordinate of snake head

for (int i = 1; i <= 2 + score; i++)
{
if ( SX == sx[i] && SY == sy[i])
gameover();
}
// Judge whether snake head touched its body. If touched, then forward to GameOver.

if (SY == FY && SX == FX)
{
RANDOM();
score ++;
Colour[0] = 40; // Set color. Parameter is R G B, range 0-255.
Colour[1] = 0;
Colour[2] = 0;
c = strip.Color(Colour[1], Colour[0], Colour[2]); //Green Red Blue  // Set color
x = light[FX][FY];                                              //Display food
strip.setPixelColor(x, c);
strip.show();//Send data
if ( !(score % 5)) {                      // Accerlerate snake speed according to the score. Every 5 foods eaten, accerlerate 100ms.
speedS = speedS - 50;
if (speedS < 150)                         // The bottom limit is 200ms. If speed lower than 200ms, the speed stays 200ms.
speedS = 150;
}
}
// Judge whether food are eaten. If snake ate food, then plus scores and regenerate food randomly.
}
```

Experiment Result

74 8.6K
105 5.3K
287 20K
90 9.4K

## Discussions

Hello,
this is a very nice project, and i have tried to implement it, but i have some problems.
my matrix is not exactly like yours, as mine is a PROGRESSIVE matrix, and i have problems with left or right direction of the snake. up and down work fine because it goes on the same line.
any ideea how to solve this? where is the matrix declared, or should i figure this out all in the code? as in the y direction every time 0 is 7 and 1 is 6 and so on .....
i'm guessing your matrix is ZIG_ZAG?
thanks