To build a Maze Runner game on your ESP32 with a joystick and a 0.9-inch OLED screen, I’ll outline the basic setup and give you the skeleton code to get started. The game will allow you to control a player (typically represented by a simple symbol) with the joystick on the OLED screen to navigate through a simple maze.
Components:
- ESP32 – Used as the microcontroller.
- Joystick – For player movement (X and Y axes).
- OLED screen – To display the maze and player.
- Push Button (optional) – For starting/resetting the game.
Wiring:
- Joystick:
VCC
to 3.3V on ESP32.GND
to GND on ESP32.X
(horizontal) to an analog pin (e.g.,GPIO34
).Y
(vertical) to an analog pin (e.g.,GPIO35
).
- OLED Screen (assuming I2C interface):
VCC
to 3.3V.GND
to GND.SDA
toGPIO21
(default).SCL
toGPIO22
(default).
Libraries Required:
- Adafruit_SSD1306 (for OLED display).
- Adafruit_GFX (for graphics functions).
- Wire (I2C communication).
Install these libraries through the Arduino Library Manager.
Code:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Joystick pins
#define JOY_X_PIN 34
#define JOY_Y_PIN 35
int playerX = 1; // Initial X position of player
int playerY = 1; // Initial Y position of player
// Define a larger, more complex maze layout
int maze[8][16] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1},
{1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1},
{1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1},
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}
};
// Destination position
int destX = 14;
int destY = 7;
void setup() {
Serial.begin(115200);
pinMode(JOY_X_PIN, INPUT);
pinMode(JOY_Y_PIN, INPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.display();
delay(2000); // Pause for 2 seconds
display.clearDisplay();
}
void loop() {
int joyX = analogRead(JOY_X_PIN);
int joyY = analogRead(JOY_Y_PIN);
// Map joystick input to movement range (-1 to 1)
int moveX = map(joyX, 0, 4095, -1, 1);
int moveY = map(joyY, 0, 4095, -1, 1);
// Update player position based on joystick movement
if (moveX > 0 && playerX < 15 && maze[playerY][playerX + 1] == 0) {
playerX++;
} else if (moveX < 0 && playerX > 0 && maze[playerY][playerX - 1] == 0) {
playerX--;
}
if (moveY > 0 && playerY < 7 && maze[playerY + 1][playerX] == 0) {
playerY++;
} else if (moveY < 0 && playerY > 0 && maze[playerY - 1][playerX] == 0) {
playerY--;
}
// Draw the maze and player
drawMaze();
display.fillRect(playerX * 8 + 2, playerY * 8 + 2, 4, 4, WHITE); // Smaller player as a 4x4 square
// Check for win condition
if (playerX == destX && playerY == destY) {
display.clearDisplay(); // Clear the display before showing the win message
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(30, 25);
display.print(F("You Win!"));
display.display();
delay(2000); // Wait for a while before resetting the game
resetGame(); // Reset the game
}
display.display();
delay(100); // Small delay to make the game playable
}
void drawMaze() {
// Draw the maze structure (walls and paths)
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 16; x++) {
if (maze[y][x] == 1) { // 1 represents a wall
display.fillRect(x * 8, y * 8, 8, 8, WHITE); // Draw walls as squares
} else { // 0 represents a path
display.fillRect(x * 8, y * 8, 8, 8, BLACK); // Fill the path area with black
}
}
}
// Draw the destination point (goal) in a different color
display.fillRect(destX * 8, destY * 8, 8, 8, WHITE); // Mark the destination with a white square
}
void resetGame() {
playerX = 1; // Reset player to start
playerY = 1;
display.clearDisplay();
drawMaze();
}
Key Points:
- Joystick Handling: The joystick is read using
analogRead()
, and the values are mapped to movement directions.- The horizontal joystick axis (
JOY_X_PIN
) controls the left-right movement of the player. - The vertical joystick axis (
JOY_Y_PIN
) controls the up-down movement.
- The horizontal joystick axis (
- Maze Representation: The maze is a 2D array where
1
represents a wall and0
represents a path. This is a very simple static maze. You can modify themaze
array for different levels. - Player Movement: The player is drawn as a rectangle. The position is updated based on the joystick input, ensuring they only move through the open paths (
maze[y][x] == 0
). - Display: The OLED screen is updated every loop cycle to show the player and the maze. And display “You Win!” after reaching destination.