Note
Hello, welcome to the SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community on Facebook! Dive deeper into Raspberry Pi, Arduino, and ESP32 with fellow enthusiasts.
Why Join?
Expert Support: Solve post-sale issues and technical challenges with help from our community and team.
Learn & Share: Exchange tips and tutorials to enhance your skills.
Exclusive Previews: Get early access to new product announcements and sneak peeks.
Special Discounts: Enjoy exclusive discounts on our newest products.
Festive Promotions and Giveaways: Take part in giveaways and holiday promotions.
👉 Ready to explore and create with us? Click [here] and join today!
GAME - Snake
This example implements the classic Snake game on an 8x12 LED matrix using the R4 Wifi board. Players control the snake’s direction using a dual-axis joystick.
Required Components
In this project, we need the following components.
It’s definitely convenient to buy a whole kit, here’s the link:
Name |
ITEMS IN THIS KIT |
LINK |
|---|---|---|
Elite Explorer Kit |
300+ |
You can also buy them separately from the links below.
COMPONENT INTRODUCTION |
PURCHASE LINK |
|---|---|
- |
|
Wiring
Schematic
Code
Note
You can open the file
13_snake.inounder the path ofelite-explorer-kit-main\fun_project\13_snakedirectly.Or copy this code into Arduino IDE.
1/*
2 This code implements a simple Snake game using an Arduino Uno R4 and a
3 Joystick Module. The Snake moves based on joystick input, and the
4 objective is to eat randomly generated food without colliding with
5 the snake's body. The game ends if the snake collides with itself.
6
7 Board: Arduino Uno R4
8 Component: Joystick Module
9*/
10
11
12#include "Arduino_LED_Matrix.h"
13
14ArduinoLEDMatrix matrix;
15byte frame[8][12];
16byte flatFrame[8 * 12]; // Flattened frame for matrix.loadPixels()
17
18// Snake variables
19struct Point {
20 byte x;
21 byte y;
22};
23
24Point snake[100];
25int snakeLength = 3;
26Point food;
27int direction = 0; // 0=up, 1=right, 2=down, 3=left
28
29void setup() {
30 pinMode(A0, INPUT); // joystick X-axis
31 pinMode(A1, INPUT); // joystick Y-axis
32
33 // Initialize LED matrix
34 matrix.begin();
35
36 // Initialize snake at middle of screen
37 snake[0] = { 6, 4 };
38 snake[1] = { 6, 5 };
39 snake[2] = { 6, 6 };
40
41 // Generate initial food
42 generateFood();
43}
44
45void loop() {
46 // Read joystick input
47 int x = analogRead(A0);
48 int y = analogRead(A1);
49
50 // Determine new direction based on joystick
51 if (x > 600 && direction != 3) direction = 1;
52 else if (x < 400 && direction != 1) direction = 3;
53 else if (y > 600 && direction != 0) direction = 2;
54 else if (y < 400 && direction != 2) direction = 0;
55
56 // Move snake
57 moveSnake();
58
59 // Check for collision with food
60 if (snake[0].x == food.x && snake[0].y == food.y) {
61 snake[snakeLength] = snake[snakeLength - 1]; // Initialize the new segment
62 snakeLength++;
63 generateFood();
64 }
65
66 // Check for collision with self
67 for (int i = 1; i < snakeLength; i++) {
68 if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
69 // Reset game (or end game)
70 snakeLength = 3;
71 snake[0] = { 6, 4 };
72 snake[1] = { 6, 5 };
73 snake[2] = { 6, 6 };
74 direction = 0;
75 generateFood();
76 }
77 }
78
79 // Draw to LED matrix
80 drawFrame();
81
82 // Delay to control speed
83 delay(200);
84}
85
86void moveSnake() {
87 for (int i = snakeLength - 1; i > 0; i--) {
88 snake[i] = snake[i - 1];
89 }
90
91 // Move the head of the snake based on the direction
92 switch (direction) {
93 case 0:
94 snake[0].y = (snake[0].y - 1 + 8) % 8; // Wrap around at the top and bottom edges
95 break;
96 case 1:
97 snake[0].x = (snake[0].x + 1) % 12; // Wrap around at the right and left edges
98 break;
99 case 2:
100 snake[0].y = (snake[0].y + 1) % 8; // Wrap around at the bottom and top edges
101 break;
102 case 3:
103 snake[0].x = (snake[0].x - 1 + 12) % 12; // Wrap around at the left and right edges
104 break;
105 }
106}
107
108void generateFood() {
109 Point possibleLocations[8 * 12];
110 int idx = 0;
111
112 // Generate all possible locations for the food
113 for (int y = 0; y < 8; y++) {
114 for (int x = 0; x < 12; x++) {
115 bool overlap = false;
116
117 // Check for overlap with the snake
118 for (int i = 0; i < snakeLength; i++) {
119 if (snake[i].x == x && snake[i].y == y) {
120 overlap = true;
121 break;
122 }
123 }
124
125 if (!overlap) {
126 possibleLocations[idx++] = { x, y };
127 }
128 }
129 }
130
131 // Randomly choose a location for the food from the possible locations
132 int choice = random(0, idx);
133 food = possibleLocations[choice];
134}
135
136void drawFrame() {
137 // Clear frame
138 for (int y = 0; y < 8; y++) {
139 for (int x = 0; x < 12; x++) {
140 frame[y][x] = 0;
141 }
142 }
143
144 // Draw snake
145 for (int i = 0; i < snakeLength; i++) {
146 frame[snake[i].y][snake[i].x] = 1;
147 }
148
149 // Draw food
150 frame[food.y][food.x] = 1;
151
152 // Flatten frame array and load into LED matrix
153 int idx = 0;
154 for (int y = 0; y < 8; y++) {
155 for (int x = 0; x < 12; x++) {
156 flatFrame[idx++] = frame[y][x];
157 }
158 }
159 matrix.loadPixels(flatFrame, 8 * 12);
160 matrix.renderFrame(0);
161}
How it works?
Here’s a detailed explanation of the code:
Variable Definition and Initialization
Import the
Arduino_LED_Matrixlibrary for LED matrix operations. matrix is an instance of the LED matrix.frameandflatFrameare arrays used to store and process pixel information on the screen. The snake is represented as an array ofPointstructures, where each point has an x and y coordinate. food represents the position of the food.directionis the current movement direction of the snake.setup()Initialize the X and Y axes of the joystick as inputs. Start the LED matrix. Initialize the snake’s starting position in the center of the screen. Generate the initial position of the food randomly.
loop()Determine the snake’s direction based on the readings from the joystick. Move the snake. Check if the snake’s head collides with the food. If it does, the snake grows, and new food is generated at a new location. Check if the snake collides with itself. If it does, reset the game. Draw the current game state (snake and food positions) on the LED matrix. Add a delay to control the game’s speed.
moveSnake()Move each part of the snake to the position of the previous part, starting from the tail and moving to the head. Move the snake’s head based on its direction.
generateFood()Generate all possible food positions. Check if each position overlaps with any part of the snake. If it doesn’t overlap, the position is considered a possible food location. Randomly select a possible food location.
drawFrame()Clear the current frame. Draw the snake and food on the frame. Flatten the two-dimensional frame array into a one-dimensional array (flatFrame) and load it onto the LED matrix.