Introduction: NeoPixels Matrix:Snake Game

Picture of 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:

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

Step 4: Experiment Result

Comments

About This Instructable

105views

1favorite

License:

Bio: ElecFreaks is an open design house founded in March 2011. Our goal is to create rapid prototypes and give small-batch manufacture solution for makers and ... More »
More by ElecFreaks:A Creative Maker in Halloween and Elecfreaks Promotion ComingNeoPixels Matrix:Snake GameTo Do PADDLEBALLSUPERSMASHEM With Micro:bit
Add instructable to: