ESP32-S3 · SSD1306 · ARCADE SHOOTER

NOVA
STRIKE

A pixel-perfect arcade shooter for embedded hardware
XIAO ESP32-S3
0.96" OLED
4 TOUCH BUTTONS
MAX98357A AUDIO
// OVERVIEW

What is Nova Strike?

Nova Strike is a full-featured arcade space shooter running entirely on a Seeed Xiao ESP32-S3 microcontroller. The game renders a parallax starfield, animated pixel-art sprites, particle explosions, and a multi-phase boss fight on a 128×64 OLED display — all at ~50 FPS. Four capacitive touch sensors or push switches give you responsive, satisfying controls. Sound effects and a startup jingle play through a MAX98357A I²S amplifier.

The entire game — 1,151 lines of C++ — runs in the ESP32's on-chip SRAM with no external storage, SD card, or PSRAM required.

1151
LINES OF CODE
~50
FPS TARGET
3
ENEMY TYPES
4
POWER-UP TYPES
WAVES
// HARDWARE

Components

MICROCONTROLLER
Seeed Xiao ESP32-S3
Xtensa LX7 @ 240 MHz · 512KB SRAM · 8MB Flash · WiFi+BT
DISPLAY
SSD1306 0.96" OLED
128 × 64 pixels · I²C interface · Monochrome · 3.3V
INPUT
TTP223 × 4
Capacitive touch · HIGH when touched · Or use push switches with 10kΩ pull-down
AUDIO
MAX98357A
I²S mono amplifier · 3.2W @ 4Ω · 5V recommended
// WIRING

Pin Connections

OLED — I²C
SDAGPIO5 (D4)
SCLGPIO6 (D5)
VCC3.3V
GNDGND
TOUCH BUTTONS
UPGPIO9 (D10)
DOWNGPIO8 (D9)
FIREGPIO44 (D7)
BOMBGPIO3 (D2)
MAX98357A — I²S
BCLKGPIO7 (D8)
LRCGPIO4 (D3)
DINGPIO2 (D1)
VIN5V (recommended)
GNDGND
NOTES
TTP223 outputs HIGH when touched (default mode A).

For push switches: connect one side to GPIO, other to 3.3V. Add 10kΩ resistor from GPIO to GND.

GPIO8 (D9) used for DOWN — GPIO2 (D1) reserved for speaker I²S DIN.
// CONTROLS

Button Layout

UP
💣
BOMB
DOWN
FIRE
UP
Move ship upward. Hold for continuous movement. Speed boost active when V power-up collected.
DOWN
Move ship downward. Same speed as UP. Symmetric movement range covers full screen height minus HUD.
FIRE
Single shot on press. Hold for rapid fire (every 4 frames). TriShot power-up adds two diagonal spread bullets.
BOMB
Smart bomb — expanding ring clears all enemies. Deals 3 HP to boss. Max 5 bombs. Starts with 3.
// GAMEPLAY

Core Mechanics

Your ship is fixed on the left side of the screen. Enemies scroll in from the right. Shoot them before they pass or collide with you. Every 10 kills advances the wave — enemies get faster, spawn faster, and become more aggressive. Every third wave spawns a boss.

Lives

Start with 3 lives. Lose one on enemy contact or boss bullet hit (unless shielded). 120-frame invincibility after each hit. Game over at 0 lives.

Scoring

Drifter: 10pts · Hunter: 20pts · Kamikaze: 30pts · Boss: 500 + wave×100. High score persists for session.

Idle Timeout

On title and score screens, a countdown bar appears after 2s. After 6s idle the game auto-returns to title with a hyperspace animation.

// ENEMIES

Enemy Types

DRIFTER
10 PTS · 1 HP
Moves straight across the screen with a slight vertical drift. First wave introduces only Drifters. Easy but abundant.
HUNTER
20 PTS · 2 HP
Slowly homes in on your Y position. Takes two hits to destroy. Appears from wave 2 onwards. Relentless.
KAMIKAZE
30 PTS · 1 HP
Hovers menacingly for 40 frames — then dashes directly at your ship at 2.2× speed. Flashes as warning before dash. Appears wave 4+.
BOSS
TITAN-CLASS WARSHIP
13×9 pixel sprite · Appears every 3 waves · HP scales with wave number (8 + wave×4)
CURRENT HP
ATTACKS
Fires 3 simultaneous bullets at set intervals. Interval shortens each wave.
REWARDS
500 + wave × 100 points
BOMB DAMAGE
3 HP per smart bomb
// POWER-UPS

Power-Up Items

Power-ups have a 20% drop chance on enemy death. They scroll left across the screen; fly into one to collect. Each is marked with a single letter on a small bordered box.

S
Shield
Absorbs one hit. Displays a flashing ring around your ship. Enemy is also destroyed on impact.
T
TriShot
Each fire now launches 3 bullets — one straight, two diagonal. Lasts 400 frames (~8 seconds).
V
SpeedBoost
1.7× movement speed. Stars streak faster in the background for visual feedback. Lasts 350 frames.
B
Bomb Refill
+1 smart bomb, capped at 5. Shown as filled circles in the bottom-right HUD area.
ACTIVE POWER-UPS HUD
While a power-up is active, its letter appears in the top-left corner of the screen. S, T, and V can be active simultaneously. Power-ups do not stack — collecting a second TriShot resets its timer.
// WAVE SYSTEM

Wave Progression

Eliminate 10 enemies to complete a wave. Speed, spawn rate, and enemy variety increase each wave. Every 3rd wave triggers a boss fight before the next wave begins.

WAVE 1
Drifters only · Slow spawn · Speed 1.25 · Learn the basics
WAVE 2
Drifters + Hunters · Medium spawn · Speed 1.5
WAVE 3 — BOSS
Titan-Class Warship · 20 HP · 3-bullet salvo every 55 frames
WAVE 4
All enemy types · Fast spawn · Speed 2.0 · Kamikazes debut
WAVE 5
All types · Very fast · Speed 2.25 · Tight gaps
WAVE 6 — BOSS
Titan-Class · 32 HP · Salvo every 40 frames · Faster movement
WAVE 7+
Speed continues scaling · Spawn rate floor at 15 frames · Boss every 3 waves forever
// HEADS-UP DISPLAY

Screen Layout

TOP-LEFT
Active power-up letters (S, T, V). Hidden when no power-up is active.
TOP-CENTER
Current wave number. Shown as "W1", "W2", etc.
TOP-RIGHT
Boss HP bar — only visible during boss encounter.
BOTTOM-LEFT
Lives remaining as small triangle ship icons.
BOTTOM-CENTER
Current score.
BOTTOM-RIGHT
Bomb count as filled circles. Dims when depleted.
// VISUAL STATES

Animations & Screens

Boot
Scanline fill → "NOVA" flash → triple invert → "STRIKE!" title burn
Title
Ship flies across screen · sine-wave underline · idle countdown bar
Wave Clear
8-arm radial burst from screen center
Boss Entry
Flashing "! BOSS !" warning · boss slides in from right
Death
12-particle explosion + expanding twin shockwave rings
Score
Star medal · score count-up · new record banner pulses
Hyperspace
Stars streak horizontally · title rebuilds letter-by-letter
Smart Bomb
Expanding double ring blast from ship position
// AUDIO

Sound Effects

All audio is synthesized in real-time using sine waves with attack/release envelopes. A non-blocking tone queue prevents sound from stalling the game loop.

SFX_JINGLE
C5 → E5 → G5 → C6 ascending arpeggio. Plays on boot and game start.
SFX_SHOOT
Short 880 Hz blip at low volume. Triggers on every bullet fired.
SFX_HIT
220 Hz thud. Plays when a bullet connects with an enemy.
SFX_EXPLODE
Two-tone descent. Enemy destruction and player death.
SFX_BOMB
Three descending tones. Deep, satisfying. Smart bomb deploy.
SFX_BOSS_DIE
5-note descending cascade. Only plays when the boss is defeated.
// INSTALLATION

Setup Guide

01
Install Arduino IDE + ESP32 Core
Add the Espressif board URL to Boards Manager: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json — then install "esp32 by Espressif Systems".
02
Install required libraries
Open Library Manager (Ctrl+Shift+I) and install: Adafruit SSD1306 and Adafruit GFX Library. Accept dependency installs.
03
Select board
Tools → Board → ESP32 Arduino → XIAO_ESP32S3. Leave all other settings at default.
04
Wire the hardware
Follow the wiring table above. The I²S speaker DIN is on GPIO2 (D1) and DOWN button is on GPIO8 (D9) — no conflicts.
05
Upload
Open NovaStrike.ino, select your COM port, and click Upload. The boot animation will play immediately after flashing completes.

Troubleshooting

OLED blank — check SDA/SCL pins, confirm I²C address is 0x3C with a scanner sketch
No sound — confirm 5V on VIN, check BCLK/LRC/DIN orientation, test with a sine wave sketch
Buttons not responding — TTP223 needs a ground connection; confirm OUT goes HIGH when touched with Serial.println
Compile errors — ensure ESP32 core version ≥ 2.x; driver/i2s.h is included in the ESP32 Arduino core, not standalone
// CUSTOMIZATION

Tuning Constants

All game-feel parameters are defined as macros near the top of the file. Easy to tweak without touching game logic.

// ── Physics ──
#define SHIP_SPD       2       // pixels per frame
#define BULLET_SPD     5       // pixels per frame
#define PIPE_GAP_HALF  11      // enemy gap half-height

// ── Difficulty ──
#define KILLS_PER_WAVE 10      // kills to advance wave
#define MAX_BULLETS    8       // bullet pool size
#define MAX_ENEMIES    10      // enemy pool size

// ── Timing ──
#define IDLE_MS        6000    // idle timeout milliseconds

// ── Power-up durations (frames) ──
ship.shieldTimer  = 300;
ship.triShotTimer = 400;
ship.speedTimer   = 350;