Im Rahmen des Praktikums zur Vorlesung The C++ Programming Language an der Universität Osnabrück hatten wir zwei Wochen Zeit, um in einem Team aus 11 Studierenden ein vollständiges Spiel inklusive Level-Editor zu entwickeln. Dabei sollten wir unter anderem mit Bibliotheken wie Box2D für die Physiksimulation und Boost sowie dem Datenformat HDF5 arbeiten. Wir entschieden uns für Bomberperson, ein von Bomberman inspiriertes Multiplayer-Spiel mit einigen zusätzlichen Spielmechaniken.
Das Spiel
Bomberperson ist ein labyrinthbasiertes Multiplayer-Spiel für 2-4 Spieler, bei dem das Ziel einfach ist: die anderen Spieler ausschalten und als Letzter übrig bleiben. Spieler können Bomben platzieren, die nach kurzer Zeit in mehrere Richtungen explodieren, Hindernisse zerstören und dabei auch andere Spieler erwischen können. Zerstörte Hindernisse können Power-ups hinterlassen, die die Fähigkeiten eines Spielers vorübergehend verbessern oder ihm das Leben schwerer machen.

Zusätzlich zum klassischen Bomberman-Gameplay haben wir eine ganze Reihe weiterer Items und Spielmechaniken eingebaut. Spieler können Münzen sammeln, sich gegenseitig Koopa-Panzer an den Kopf werfen und verschiedene Upgrades aufsammeln, die ihre Laufgeschwindigkeit, Explosionsreichweite, Stärke, Unverwundbarkeit oder Lebenspunkte erhöhen. Allerdings sind nicht alle Items hilfreich: Manche verlangsamen die Spieler oder lösen sogar Explosionen aus.
Außerdem gibt es verschiedene Bodenbeläge, die beeinflussen, wie sich die Spieler durch das Level bewegen. Schlamm verlangsamt sie, Öl macht den Untergrund rutschig, Speedpads beschleunigen oder bremsen sie ab und ein spezieller Geisterteppich ermöglicht es, durch Wände zu laufen. Objekte besitzen unterschiedliche physikalische Eigenschaften und Interaktionsmöglichkeiten: Manche können durch Explosionen zerstört werden, andere lassen sich schieben, ziehen oder durch die Gegend werfen. Wer von einer Explosion erwischt wird, stirbt, während ein Treffer mit einem Koopa-Panzer Lebenspunkte kostet.
Das Spiel unterstützt sowohl Tastatur- als auch Gamepad-Steuerung, enthält Soundeffekte und bietet mehrere Level mit unterschiedlichen Themen, darunter auch eines auf dem Mond.
Der Level-Editor
Neben dem eigentlichen Spiel haben wir einen Level-Editor entwickelt, mit dem Spieler eigene Karten erstellen oder bestehende verändern können. Darin lassen sich Wände, Hindernisse, Items und Startpositionen platzieren, verschiedene Tilesets auswählen oder eigene Tilesets importieren.
Die Level werden als XML-Dateien gespeichert, die neben dem Aufbau der Karte auch verschiedene Gameplay- und Physikparameter enthalten. Dazu gehören unter anderem die Laufgeschwindigkeit der Spieler, die Reichweite von Bomben, die Spieldauer, Reibung, Dämpfung und Bewegungskräfte. Dadurch können sich Level nicht nur optisch, sondern auch spielerisch und physikalisch deutlich unterscheiden.
Der Editor unterstützt bis zu vier Startpositionen für Spieler, wobei mindestens eine vorhanden sein muss, um ein Level speichern zu können. Die erstellten Level lassen sich anschließend direkt im Spiel laden und spielen.
Die technische Umsetzung
Technisch basiert Bomberperson auf einer eigenen C++-Spielengine, die auf SDL, Box2D und Boost aufbaut.
Im Zentrum steht die Klasse Game, die das Spielfenster, den Physikkontext und das aktuell geladene Level verwaltet. Die Klasse Level enthält sämtliche Spielobjekte, die in getrennten Collections für Tiles, Items und Spieler organisiert sind.
Die Architektur basiert auf einer gemeinsamen Basisklasse Entity, die die von den verschiedenen Objekttypen benötigte Funktionalität bereitstellt. Jede Entity implementiert eine tick()-Methode, die ihren Zustand während der Spielschleife aktualisiert, sowie Methoden für die Interaktion mit anderen Objekten, beispielsweise gotHit(). Die render()-Methode des Levels iteriert anschließend über die Entities, um sie an ihren aktuellen Positionen darzustellen.
Die Physiksimulation läuft separat über Box2D. Jede Entity im Spiel besitzt eine zugehörige Physik-Entity, die vom PhysicsContext verwaltet wird und ihre Position sowie ihre physikalischen Interaktionen bestimmt. Beim Rendern eines Objekts wird dessen Position direkt aus der Physiksimulation übernommen, anstatt sie separat im Rendering-Code zu verwalten.
Um die große Anzahl unterschiedlicher Objekte und Texturen zu verwalten, haben wir außerdem mehrere Factories implementiert. Die ItemFactory kann beispielsweise zufällige Items an einer bestimmten Position erzeugen, wenn ein Hindernis zerstört wird. Andere Objekte, etwa Kisten, Ölfelder und spezielle Bodenbeläge, werden direkt anhand der Levelkonfiguration erstellt.
Die Texture-Factory lädt und dedupliziert Texturen, sodass nicht unnötig mehrere Kopien derselben Ressourcen im Speicher liegen. Außerdem verwaltet sie animierte Sprites und deren Frame-Updates. Bei Objekten, die synchron animiert werden sollen, beispielsweise mehreren identischen Kisten, werden die Animationen synchronisiert, statt dass jedes Objekt seine Animation unabhängig abspielt.
Durch die vielen unterschiedlichen Entity-Typen, ihre Interaktionen und ihre physikalischen Eigenschaften wurde das Spiel letztendlich deutlich komplexer als ein einfacher, rasterbasierter Bomberman-Klon. Insbesondere wenn man bedenkt, dass wir das Ganze inklusive Level-Editor in nur zwei Wochen entwickelt haben!
Gameplay-Video
Leider mussten wir eine restriktive Lizenz verwenden, weshalb ich aktuell keine spielbare Version des Spiels zur Verfügung stellen kann. Hier gibt es aber ein Video, das das Spiel in Aktion zeigt: