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.
Step 1: Components List:
Hardware:
1 X Freaduino UNO Rev2.2 MB_EFUNO
1 X Flexible 64 RGB LED 8*8 NeoPixels Matrix
1 X Joystick breakout module BKOUT_MD01
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]; Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 ); 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
Comments
Question 4 years ago on Step 4
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