Pixel Chase: a Retro Arcade Game With ESP32 / Arduino
by anoofc in Circuits > Arduino
588 Views, 5 Favorites, 0 Comments
Pixel Chase: a Retro Arcade Game With ESP32 / Arduino
Pixel Chase, a fun and engaging arcade game built with the ESP32/Arduino microcontroller!
The Challenge:
Pixel Chase presents a simple yet addictive gameplay experience. You'll see four LEDs arranged in a circle. Three will remain stationary, while the fourth will continually move around the perimeter. Your objective? Time your button presses perfectly!
- Start the Game: A single press of the button initiates the challenge.
- Capture the Pixel: As the moving LED ventures inside the stationary circle formation, press the button again. Capture it at the right moment to score.
- Success or Failure?
- Correct Timing: If you hit the button with precision, the next color in the sequence will flash momentarily before the moving pixel resumes its circular dance.
- Wrong Timing: A misstep results in game over.
- Scoring System: Every successful capture updates the score displayed on the 7-segment display. With each point, the moving pixel speeds up, increasing the difficulty.
- Victory! Achieve a score of 20, and you'll be rewarded with a dazzling rainbow animation on the LED ring, celebrating your triumph!
Building Your Own Pixel Chase?
This post will guide you through building your very own Pixel Chase game with the ESP32 or Arduino. We'll delve into the required hardware, software setup, and code breakdown, equipping you to create a captivating retro experience. Get ready to unleash your inner arcade champion!
Supplies
Hardware components
Espressif ESP32 Development Board - Developer Edition
WS2813 RGB LED Strip Waterproof - 60 LED/m - 1m
7 Segment LED Display Common Cathod 2 inch
74HC595N Serial In Parallel Out Shift Register IC
5V 2.5A Switching Power Supply
Hook Up Wire Kit, 22 AWG
Ceramic Disc Capacitor, 0.1 µF
Dot PCB Generic
Software apps and online services
Hand tools and fabrication machines
Wire Stripper
Soldering iron (generic)
Solder Wire, Lead Free
Get Hardware
- Microcontroller: Any Arduino-based microcontroller will be good for this project. I'm using the ESP32 Dev Module from Espressif so that I can expand this project by adding more features by using the possibilities of Wireless communication methods of the ESP32 Module.
- Neopixel LED Strip: You'll need a 60 LED/m Addressable LED Strip (Neopixel) with 5v Input voltage. These will be arranged in a circular pattern to create the visual elements of the game.
- Push Button: A giant push button will be used to start the game and capture the moving pixel. A 0.1uf (104) Ceramic capacitor is better to be used to avoid mis-triggering of the button due to noise issues.
- 7 Segment Display: This will be used to display the player's score throughout the game. I'm using two Large 2" Common Cathode Displays for displaying two-digit scores.
- 74HC595N Shift Register: 74HC595N is an 8-bit Serial in, Serial/Parallel out shift register with output latches. You can use it to control 8 outputs at a time while only taking up a few pins on your microcontroller. You can link multiple registers together to extend your output even more. These qualities make it the right choice for driving a 7-segment Display.
- Current-Limiting Resistors: Appropriate resistors will be needed to protect the Display segments and ensure they operate within their specified current range. I've taken 100 ohms Resistors as my display is quite large and the IC I'm using to drive cannot supply that much current to burn the LED segments.
- 5V Power Supply: A 5V power supply will provide the necessary voltage to power the ESP32, Neopixel Strip, 7-segment display, and other components.
- Enclosure: An enclosure can be used to house the components and give the game a more finished appearance. I'm using a structure made by CNC Engraving an MDF wood piece. My colleague Praveen designed the file for CNC engraving Using Solid Works Software. You can Design your enclosure and 3D print it if you don't have access to a CNC Engraving Machine. I will attach the Solid Works file for you if you want to use the same design as me.
- Diffusing Top Cover: I used a Light pass Acrylic Sheet with 2 mm thickness cut using laser machine. Also I used small PVC Pieces to separate individual LED pixels.
Connecting Hardware
- Push Button: Connect the Push Button to GPIO 26 of ESP32, or any other pin as you like.
- LED Strip: Connect the data pin of LED strip to GPIO27, +ve to 5v and Gnd to Ground of ESP32. Be mindful of the Data flow of the Neopixel strip should be as per the arrow mark in the LED Strip. Refer the Connection Diagram if you have any doubts.
- 5vAdapter: To power up the whole LED strip and ESP32, I'm using a 5v 2A power adapter, I cut the wire and added a JST connector, so that I can connect easily.
- 7 Segment Display: Connect the 7 Segment display Common pins to ground as I'm using a common cathode one. If you have the common anode type connect common to the 5v pin. We need a shift register to drive the 7 Segment Display. I have taken a 74HC595N 8 bit Shift register. Connect the Data pin (SER/14) to the GPIO 23, Clock to GPIO19 and Latch Pin to GPIO21. Refer to the Circuit diagram for more info. For the second digit, everything goes the same except the Data pin is connected to the Data out of first 74hc595 IC.
Software Setup
Configuring Arduino IDE for ESP32 Development
- Download and Install Arduino IDE: Visit the Arduino website: Go to https://www.arduino.cc/en/Main/Software. Download the latest version: Choose the appropriate version for your operating system (Windows, macOS, or Linux).
- Install the IDE: Follow the on-screen instructions to complete the installation process.
- Install ESP32 Board Support: Open Arduino IDE: Launch the Arduino IDE.
- Go to "File" -> "Preferences": This will open the preferences window.
- Add the ESP32 board manager URL: In the "Additional Boards Manager URLs" field, enter the following URL: https://dl.espressif.com/package/esp32/index.json
- Click "OK": Save the changes.
- Install ESP32 Board: Go to "Tools" -> "Board": This will open the board manager. Search for "ESP32": Type "ESP32" in the search bar.
- Click the "Install" button to download and install the necessary libraries and tools.
- Select your ESP32 board: Go to Tools -> Boards -> ESP32 and Choose the specific ESP32 board model you are using (e.g., ESP32-DevKitC, ESP32-Wrover-B).
- Select the correct port: Connect your ESP32: Connect your ESP32 board to your computer using a USB cable. Check the port: Go to "Tools" -> "Port" and select the correct serial port that corresponds to your ESP32 board. You may need to consult your device manager or system settings to identify the correct port.
- Verify the installation: Create a simple blink example: Open a new Arduino sketch and paste the following code:
- Upload the sketch: Click the "Upload" button to compile and upload the sketch to your ESP32.
- Observe the LED: If the built-in LED on your ESP32 board blinks, the installation was successful.
Additional tips:
Update the IDE: Keep your Arduino IDE updated to ensure compatibility with the latest ESP32 features and bug fixes.
Consult documentation: Refer to the official ESP32 documentation and community forums for more in-depth information and troubleshooting tips.
Code Breakdown
Libraries Used
- Adafruit_NeoPixel.h: Library to control NeoPixel LED strips.
- ShiftRegister74HC595.h: Library for controlling shift registers like 74HC595.
Pin Configuration
- Button Pin: GPIO 26 (BUTTON_PIN)
- NeoPixel Pin: GPIO 27 (PIXEL_PIN)
- Shift Register Pins: Data - GPIO 23, Clock - GPIO 21, Latch - GPIO 19
Constants:
- NUM_PIXELS - Total number of pixels in your strip
- SPEED - Initial Speed (Delay) of the running pixel. Decreases as level up.
- FINAL_LEVEL - Final Speed (Delay) of the running pixel.
Include Necessary Libraries:
Create Objects for Initializing Shift register and Neopixel.
Global Variables:
Blink the Seven Segment Display 3 times
Display Score on Seven Segment Display:
This function takes an unsigned 16-bit integer score as input and displays it on the screen. It extracts the individual digits of the score and maps them to corresponding binary patterns stored in the numberB array. The digits are then passed to the sr.setAll() function to display the score on the screen.
Wheel Function to create a rainbow color:
- This function takes a wheel position as input and returns a color value based on the position.
- The wheel position is used to calculate the RGB values of the color.
- The color generated follows a specific pattern where the RGB values change based on the wheel position.
- byte WheelPos is the position of the wheel (0-255).
- Return The color value generated based on the wheel position.
Rainbow cycle function:
- This function iterates through each pixel and sets its color based on a cycling rainbow pattern.
- The rainbow pattern is created by calculating the color value using the Wheel function.
- The function delays for a specified amount of time after setting the color of each pixel.
Color chase function:
- Animates a color chase effect on a strip of NeoPixels.
- This function sets the color of each pixel in a NeoPixel strip to the specified color 'c' and then displays the updated strip.
- The function iterates through each pixel in the strip and sets its color to 'c' one by one, creating a chasing effect. The function delays for a specified amount of time after setting the color of each pixel.
Game over function: Function to handle the game over state. This function is called when the game is over. It performs the following actions:
- Initiates a color chase with black color on the neopixels.
- Flashes the neopixels three times by filling them with red color and then black color.
- Displays the score on a display three times.
- Resets the score to 0 and displays it.
- Sets the game state to false.
- Prints "Game Over" if the DEBUG flag is enabled.
Button state handler: Handles the state of the button. This function checks if the button is pressed and updates the button state accordingly. If the button is pressed and the button state is false, the button state is set to true.
- newTargetHandler Function :
- Handles the creation of a new target in the game.
- This function is responsible for generating a new target in the game.
- It randomly selects a position between 5 and NUM_PIXELS-5 and sets the corresponding pixels' colors.
- The x pixel color is set to white, the y pixel color is set to the next color in the sequence, and the z pixel color is set to white.
- If the DEBUG flag is enabled, it also prints the values of x, y, and z to the serial monitor.
Game running handler:
- Handles the running of the game. This function is responsible for running the game. It updates the position of the light on the strip,
- checks if the button is pressed, and updates the score and speed accordingly.
- If the button is pressed when the light is on the target color, the score is incremented, the neopixels are filled with the next color, and the speed is updated.
- If the button is pressed when the light is not on the target color, the game is over, the score is reset, and the speed is set to the initial value.
- If the speed reaches the final level, the game is over, and the score is reset.
- The function also prints the level, speed, and score to the serial monitor if the DEBUG flag is enabled.
Setup function: This function initializes the serial communication, sets the button pin as input pullup, begins the neopixels, sets the brightness of the neopixels, and calls the blink and displayScore functions.
Loop function: This function checks if the game is running and calls the buttonStateHandler, newTargetHandler, and gameRunningHandler functions accordingly.
If the game is not running and the button is pressed, the game state is set to true.
Game Logic and Flow
- Game Start: The game starts when the button is pressed. The initial speed of the moving light is set, and the NeoPixel strip is ready.
- Game Running: A target color is randomly selected on the NeoPixel strip. The light moves along the strip. The player's goal is to press the button when the light reaches the target color. If the player presses the button at the correct time, the score increases, and the speed of the light increases, making the game more challenging. If the player presses the button when the light is not on the target color, the game ends. If the speed exceeds a certain threshold, the game also ends.
- Game Over: When the game ends, a rainbow effect is displayed on the NeoPixel strip, indicating the end of the game. The score is reset, and the game can be restarted.
- Score Display: The current score is displayed on a 7-segment display using a shift register.
Downloads
Final Code
Downloads
Suggestions/feedback
Customization
You can easily modify the game's difficulty by adjusting the SPEED, FINAL_LEVEL, and LEVEL constants. The colors used in the game can also be changed by modifying the colors[] array.
Suggestions/feedback
If you have any suggestions or feedback feel free to comment down below. If you encounter any problems during the making of the project, don't hesitate to contact me. I will be updating this library to improve efficiency and include more functions soon.
Connect me on LinkedIn: Connect Now