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