Der Retro Pixel Racer ist ein kleines Arcade-Spiel für den Arduino UNO, das auf einem 128×64 OLED-Display läuft. Angelehnt an die klassischen Rennspiele der 80er-Jahre steuerst du als Spieler ein Fahrzeug über mehrere Fahrspuren und musst dabei den anderen Fahrzeugen ausweichen. Das Projekt nutzt einfache Hardware-Komponenten und zeigt eindrucksvoll, wie auch mit minimalistischen Mikrocontrollern halbwegs flüssige Animationen realisiert werden können.
Trotz des einfachen Aufbaus des Projekts zu geringen Kosten ist das Ergebnis recht spannend und eignet sich auch gut für Gruppenprojekte, z.B. in der Schule.
Hardware-Anforderungen
Neben dem Arduino samt Breadboard, das in vielen Starter Kits enthalten ist, benötigt man lediglich ein zusätzliches OLED-Display mit SSD1306-Controller sowie zwei Push-Buttons für die Steuerung. Ein optionaler Buzzer sorgt für Soundeffekte.

Für den Nachbau werden folgende Komponenten benötigt:
- OLED I2C Display 128×64 mit SSD1306 (separat erhältlich, z.B. hier im 3er Pack bei Amazon)
und die folgende Teile, die in jedem Arduino Starter Kit enthalten sind:
- Arduino UNO R3 (oder kompatibel) mit Breadboard
- Zwei Push-Buttons für die Steuerung (links/rechts)
- Optionaler Buzzer für Soundeffekte
- Ein paar Kabel zur Verbindung der Komponenten
Verkabelung:

Der Buzzer an D6 kann auch einfach weggelassen werden, im Programmcode sind dazu keine Änderungen notwendig.
Komponente | Arduino Pin |
---|---|
OLED SDA | A4 |
OLED SCL | A5 |
OLED VCC | 5V |
OLED GND | GND |
Button Links | D2 und GND |
Button Rechts | D3 und GND |
Buzzer | D6 und GND |
Arduino Programmcode und technische Besonderheiten
Der komplette Quellcode ist gut dokumentiert auf GitHub (oled_racer_de.ino) verfügbar. Am einfachsten beim grünen Button rechts oben „Download ZIP“ wählen und entpacken – oder den Sketch einfach über die Zwischenablage in ein neues Arduino Programmfenster kopieren.
Einige wichtige Aspekte zum Verständnis des Codes:
Optimierung durch Integer-Skalierung:
Rechenoperationen mit Gleitkommazahlen sind aufwändig und das wollte ich vermeiden. An manchen Stellen, zum Beispiel bei der Geschwindigkeit des Spielerautos, braucht man aber die Möglichkeit, diese in feineren Schritten zu erhöhen. Deswegen habe ich Koordinaten von Objekten am Display und Geschwindigkeiten um den Faktor 10 hochskaliert und als int gespeichert. Das Display hat also im Programmcode nicht 128×64, sondern 1280×640 Pixel. So sind präzisere Berechnungen ohne Performance-Einbußen durch Float-Operationen möglich. Vor der Darstellung auf dem Display werden die Werte dann durch 10 geteilt.
Beispiel:playerSpeed = 25
bedeutet eine Bewegung von 2.5 Pixeln pro Frame.
Ein Hindernis mit x = 150
befindet sich an Position x = 15.0 auf dem Display.
Spielzustände verwalten:
Der Code nutzt eine enum GameState
, um zwischen den verschiedenen Zuständen zu wechseln:STARTSCREEN
: Intro-Animation mit Titel.PLAYING
: Das eigentliche Spiel läuft (oder zeigt „Game over an“)HIGHSCORE
: Nach Game Over wird eine Highscore-Liste angezeigt.
Dadurch bleibt der Code sauber strukturiert und einfach erweiterbar.
Flüssige Animationen mit Timer-Steuerung:
Das Spiel nutzt millis(), um eine konstante Framerate von 25 FPS zu halten. Statt delay() wird der Zeitunterschied zum letzten Frame berechnet, sodass die Spiellogik immer genau zur richtigen Zeit aktualisiert wird.
Adaptive Gegner-Spawns:
Die Gegner (Hindernisse) erscheinen mit steigender Spielzeit immer häufiger. Zu Beginn gibt es nur einen Gegner gleichzeitig, später bis zu zehn, je nach zurückgelegter Distanz.
Blinkende Highscore-Anzeige:
Falls der aktuelle Score in die Top-10 kommt, wird dieser blinkend hervorgehoben.
Vorbereitung der Spielgrafik
Da das OLED-Display nur Schwarz-Weiß-Grafiken unterstützt, müssen Bilder in ein passendes Bitmap-Format umgewandelt und im Programmcode eingebunden werden. Dafür habe ich das kostenlose Online-Tool Image2CPP verwendet.
Schritt-für-Schritt-Anleitung für eigene Grafiken:
- Lade das gewünschte PNG-Bild hoch.
- Stelle die Bildgröße passend zur benötigten Pixelgröße ein (z. B. 10×8 Pixel für ein Auto).
- Wähle als Ausgabeformat → Arduino Code.
- Kopiere den generierten PROGMEM-Code in das Arduino-Projekt.
- Nutze display.drawBitmap(x, y, bitmap, width, height, SSD1306_WHITE); zur Anzeige des Bildes.
Diese Methode ermöglicht es, eigene Icons oder Sprites für das Spiel zu erstellen und ins Flash-Speicher (PROGMEM) des Arduino zu laden. Dabei muss man aber immer beachten, dass der Speicherplatz des Arduino sehr begrenzt ist :)
Spielprinzip und Steuerung
- Der Spieler kann sich mit den beiden Buttons nach links und rechts bewegen.
- Gegner erscheinen zufällig auf den Spuren und bewegen sich auf den Spieler zu.
- Kollidiert der Spieler mit einem Hindernis, ist das Spiel vorbei.
- 3 Sekunden nach Game over wird die Highscore-Liste angezeigt.
- Ein Druck auf eine beliebige Taste startet das Spiel neu.

Was mir am Projekt gefällt
Dieses kleine Projekt zeigt, dass auch mit begrenzten Ressourcen spannende Retro-Spiele auf dem Arduino möglich sind. Der Code ist modular und halbwegs verständlich – auf Objektklassen oder komplexere Konstrukte habe ich bewusst verzichtet – und kann leicht verändert oder erweitert werden – beispielsweise mit mehr Soundeffekten oder zusätzlichen Hindernissen.
Der komplette Quellcode ist auf GitHub verfügbar. Viel Spaß beim Nachbauen!