-
1BREADBOARD ASSEMBLY
![]()
![]()
![]()
![]()
![]()
- To begin assembly, we place the XIAO ESP32 C6 microcontroller on the breadboard. Then, we add the Push Button next to it.
- We begin the wiring process by connecting the matrix's VCC to XIAO's 5V.
- GND of the matrix is then connected to GND of the XIAO.
- We wired one terminal of the Push Button to GND and the other to GPIO 1.
- The matrix data wire connects to the GPIO0 of the XIAO.
The wiring process is now completed.
-
2CODE
This was the code used in this project and it's a simple one.
#include <Adafruit_NeoMatrix.h> #define MATRIX_PIN 0 #define MATRIX_WIDTH 16 #define MATRIX_HEIGHT 8 Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS, NEO_GRB + NEO_KHZ800); #define BUTTON_PIN 1 int birdY = MATRIX_HEIGHT / 2; struct Pillar { int x; int gapStart; int gapHeight; }; Pillar pillars[5]; int gameSpeed = 200; // Initial game speed int difficultyCounter = 0; // Difficulty tracking void setup() { matrix.begin(); matrix.setBrightness(50); matrix.fillScreen(0); matrix.show(); pinMode(BUTTON_PIN, INPUT_PULLUP); for (int i = 0; i < 5; i++) { pillars[i].x = MATRIX_WIDTH + i * 8; pillars[i].gapStart = random(2, MATRIX_HEIGHT - 2); pillars[i].gapHeight = 3; } Serial.begin(115200); } void loop() { matrix.fillScreen(0); // Bird movement based on button hold if (digitalRead(BUTTON_PIN) == LOW) { birdY -= 1; // Bird moves upward while button is held } else { birdY += 1; // Gravity pulls bird downward when button is released } // Clamp bird position to stay within matrix bounds if (birdY < 0) birdY = 0; if (birdY >= MATRIX_HEIGHT) birdY = MATRIX_HEIGHT - 1; // Draw bird matrix.drawPixel(3, birdY, matrix.Color(255, 255, 0)); // Yellow bird // Move and draw pillars uint32_t pillarColor = matrix.Color(128, 0, 128); // Purple for initial difficulty if (difficultyCounter > 50) { pillarColor = matrix.Color(255, 0, 0); // Transition to red for higher difficulty } for (int i = 0; i < 5; i++) { pillars[i].x--; if (pillars[i].x < 0) { pillars[i].x = MATRIX_WIDTH; pillars[i].gapStart = random(2, MATRIX_HEIGHT - 2); difficultyCounter++; } for (int y = 0; y < MATRIX_HEIGHT; y++) { if (y < pillars[i].gapStart || y > pillars[i].gapStart + pillars[i].gapHeight) { matrix.drawPixel(pillars[i].x, y, pillarColor); } } } // Collision detection for (int i = 0; i < 5; i++) { if (pillars[i].x == 3 && (birdY < pillars[i].gapStart || birdY > pillars[i].gapStart + pillars[i].gapHeight)) { matrix.fillScreen(matrix.Color(255, 0, 0)); // Game over matrix.show(); delay(2000); setup(); // Restart game return; } } matrix.show(); if (difficultyCounter % 10 == 0 && gameSpeed > 150) { gameSpeed -= 5; } delay(gameSpeed); }Let's have a brief breakdown of our code.
We use the Adafruit_NeoMatrix.h library to control the 16x8 WS2812B LED matrix. This library helps us draw pixels, shapes, and animations.
#define MATRIX_PIN 0 #define MATRIX_WIDTH 16 #define MATRIX_HEIGHT 8 Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS, NEO_GRB + NEO_KHZ800); #define BUTTON_PIN 1The matrix is initialized to match its physical layout and color format.
BUTTON_PIN connects to a button, which controls the bird's movement.
int birdY = MATRIX_HEIGHT / 2; // Bird starts in the middle vertically struct Pillar { int x; // Horizontal position int gapStart; // Starting position of the gap int gapHeight; // Gap height }; Pillar pillars[5];The bird's vertical position (birdY) is tracked.
Pillars are defined with x (horizontal position), gapStart (gap's position), and gapHeight (size).
void setup() { matrix.begin(); matrix.setBrightness(50); // Set LED brightness matrix.fillScreen(0); // Clear the matrix matrix.show(); pinMode(BUTTON_PIN, INPUT_PULLUP); // Button setup for (int i = 0; i < 5; i++) { pillars[i].x = MATRIX_WIDTH + i * 8; // Spacing pillars evenly pillars[i].gapStart = random(2, MATRIX_HEIGHT - 2); // Random gaps pillars[i].gapHeight = 3; // Fixed gap height } Serial.begin(115200); // Serial for debugging}This Section prepares the LED matrix, sets the button pin as input, and initializes the pillars.
if (digitalRead(BUTTON_PIN) == LOW) { birdY -= 1; // Button pressed, bird goes up} else { birdY += 1; // Button released, gravity pulls bird down}if (birdY < 0) birdY = 0; // Prevent bird going off-screenif (birdY >= MATRIX_HEIGHT) birdY = MATRIX_HEIGHT - 1;matrix.drawPixel(3, birdY, matrix.Color(255, 255, 0)); // Draw yellow birdThe button controls the bird's movement, simulating gravity when released.
The bird's position is clamped within screen bounds and drawn at x=3 .
pillars[i].x--;if (pillars[i].x < 0) { pillars[i].x = MATRIX_WIDTH; // Reset pillar position pillars[i].gapStart = random(2, MATRIX_HEIGHT - 2); // New random gap}for (int y = 0; y < MATRIX_HEIGHT; y++) { if (y < pillars[i].gapStart || y > pillars[i].gapStart + pillars[i].gapHeight) { matrix.drawPixel(pillars[i].x, y, matrix.Color(128, 0, 128)); // Draw purple pillars }}Pillars move left and reset with new gap positions when they leave the screen.
if (pillars[i].x == 3 && (birdY < pillars[i].gapStart || birdY > pillars[i].gapStart + pillars[i].gapHeight)) { matrix.fillScreen(matrix.Color(255, 0, 0)); // Red screen for Game Over matrix.show(); delay(2000); setup(); // Restart game return;}This Checks if the bird hits a pillar (outside the gap) and Displays "Game Over" in red, then restarts the game.
if (difficultyCounter % 10 == 0 && gameSpeed > 150) { gameSpeed -= 5; // Gradually increase game speed}delay(gameSpeed);The game gets harder as the pillars move faster over time.
-
3RESULT and What's next.
Here's the ultimate result of this small build: a working Flappy Bird-like game running on an ESP32-based development board utilizing a custom matrix panel.
We control the movement of the Bird or Pixel using the Push Button; as time passes, the difficulty of the game increases. If we hit any buildings, we are presented with a RED Screen, indicating that the game has ended; the game then resets, and the cycle repeats again.
This is a test project for a small handheld gaming console project that will consist of a single custom matrix PCB with buttons. games will be programmed for that display, and it will look like a Game Boy or similar device but with an RGB LED display. More on the project in the coming months.
Check out a similar project called the Snake game project, which uses PICO 2 and a P64 matrix to run a customized Snake game.
https://www.hackster.io/Arnov_Sharma_makes/snake-game-console-07b378
Leave a comment if you need any help regarding this project. This is it for today, folks.
Thanks to Seeed Studio Fusion for supporting this project.
You guys can check them out if you need great PCB and stencil service for less cost and great quality.
And I'll be back with a new project pretty soon!
Arnov Sharma




Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.