Dungeon Crawler v1.4
Über das Projekt
Was ist der Dungeon Crawler?
Der Dungeon Crawler war mein erstes größeres C-Projekt. Ziel war es, ein vollständig spielbares Spiel mit Standard-C zu bauen.
Die Karte wird aus einem zweidimensionalen Array aufgebaut. Wände, freie Felder, Gegner und Items haben jeweils eigene Zeichen. Der Spieler bewegt sich mit den Pfeiltasten und muss Gegnern ausweichen, während er Schätze einsammelt.
Features
Was kann das Spiel?
- Grafisches Rendering — Das Spiel läuft in einem raylib-Fenster (1280×720); Karte, Spieler, Gegner und Effekte werden GPU-beschleunigt gezeichnet.
- Spielerbewegung — Steuerung mit WASD oder Pfeiltasten, Kollisionserkennung mit Wänden, Fallen und anderen Objekten.
- Gegner-KI — Gegner verfolgen aktiv den Spieler (Pathfinding entlang X/Y-Achse); bei Kontakt stirbt der Spieler. Gegner können per Taste ein- und ausgeschaltet werden.
- Rundenbasiertes Fortschrittssystem — Jede Runde besteht aus einer prozedural generierten Karte. Der Schatz beendet die Runde; ein Portal überspringt direkt zur nächsten.
- Münzen & Fallen — Münzen ($) erhöhen den Punktestand. Fallen (+) töten den Spieler sofort, sofern kein Schild aktiv ist.
- Partikeleffekte & Kamera — Explosionen, Münzfunken und Todeseffekte als Partikelsystem; die Kamera folgt dem Spieler weich durch die Karte.
- Highscore & Persistenz — Beste Runde, meiste Schätze, meiste Münzen und gesamte Lifetime-Coins werden in einer Datei gespeichert und im Menü angezeigt.
- Game Over & Neustart — Nach dem Tod kann das Spiel neu gestartet oder ins Hauptmenü gewechselt werden.
- Item-System (5 Typen, upgradebar) — Bis zu 3 Items im Inventar, ausrüstbar mit Tasten 1/2/3. Jedes Item lässt sich im Shop einzeln in bis zu 6 Stufen aufwerten:
- SPD – Erhöht die Bewegungsgeschwindigkeit; Dauer steigt mit dem Upgrade-Level.
- SHD – Schild absorbiert Treffer für begrenzte Zeit, ab der höchsten Stufe permanent.
- BMB – Bombe zerstört Fallen im Umkreis; Radius wächst mit dem Level.
- WLK – Ghostwalk: Spieler geht durch Wände; Dauer steigt mit dem Level.
- SWD – Schwert tötet Gegner im Umkreis; Reichweite wächst mit dem Level.
- Achievements — Eigenes Menü mit 7 Erfolgen (u. a. gespielte Runden, gesammelte Münzen, Kills), jeweils in 3 Stufen mit Fortschrittsbalken.
- 30 Skins in 4 Rarity-Stufen — Common, Uncommon, Rare und 3 animierte Epic-Skins (Alien, Skull, Angel), käuflich im Shop.
- Settings-Menü — Erste Spieloptionen wie Gegner an/aus, weitere folgen in Kürze.
Zukünftige Features
Was wird noch kommen?
- v1.5 „Legacy of Stars“ — Achievement-Überarbeitung auf 6 Stufen mit Coin- und Skin-Belohnungen, 10+ neue Achievements.
- Musiksystem — Hintergrundmusik und Soundeffekte über raylib AudioStream.
- 8 neue Skins + 3 Legendary-Skins — Legendary-Skins exklusiv über Tier-6-Achievements freischaltbar.
- Erweiterte Settings — Audio-Regler und weitere Gameplay-Optionen.
- Code-Architektur — Aufteilung der bisher einzelnen .c-Datei in mehrere Module.
Screenshots
Einblicke ins Spiel
Die Karte mit Spieler, Gegnern und Items
Links: Startmenü · Rechts: Game Over
Technisches
Wie wurde es gebaut?
Das gesamte Projekt besteht weiterhin aus einer einzigen .c-Datei, mittlerweile auf ~3.350 Zeilen Code angewachsen, gebaut mit raylib — einer C-Bibliothek für 2D/3D-Grafik.
Die Karte ist ein statisches 2D-Array aus char-Zeichen (char map[MAP_ROWS][MAP_COLS]),
wird aber prozedural generiert und nicht hardcoded.
for (int y = 0; y < mh; y++)
for (int x = 0; x < mw; x++) {
int r = GetRandomValue(0,99);
map[y][x] = (r < tp) ? '#' : (r < xp) ? '+' : '.';
}
/* Tile-Map-Konstanten */
'#' = Wand, '.' = Boden, '+' = Falle
'T' = Schatz, 'O' = Portal, '$' = Münze
'I' = Item, 'X' = Gegner
Rendering mit raylib: Jedes Tile wird als 32×32 Pixel gerendert — Wände bekommen 3D-Bevel-Effekte, Items und Gegner sind animierte Formen/Kreise. Die Kamera folgt dem Spieler weich; Partikeleffekte werden pro Frame aktualisiert.
Eingabe mit raylib: Tasteneingaben erfolgen über IsKeyPressed() und IsKeyDown() — plattformübergreifend ohne spezielle Anpassungen nötig.
Spiellogik: Eine State Machine (`GState`: MENU → PLAY → DEAD/NEXT) steuert den Flow. Die Hauptschleife nutzt Delta-Time (`GetFrameTime()`) für konstante Physik — 60 FPS. Gegner-KI, Partikel, Timer und Kamerabewegung werden alle frame-unabhängig mit `dt` aktualisiert.
Persistenz: Highscores (beste Runde, Schätze, Münzen) werden in eine Datei geschrieben und geladen (`STATS_FILE`).
Shop & Fortschritt: Jedes der 5 Items hat ein eigenes Upgrade-Level, das per Array (Dauer/Reichweite pro Stufe) ausgelesen wird; Skin-Besitz, Levels und Coins werden separat gespeichert (`SHOP_FILE`). Die 30 Skins sind nach Seltenheit gestaffelt und je nach Stufe mit eigenen Zeichenfunktionen gerendert — von einfarbigen Common-Skins bis zu animierten Epic-Skins. Achievements laufen über dieselben Stats-Werte und werden live mit Zielwerten je Stufe abgeglichen.
Rückblick
Was ich gelernt habe
Dieses Projekt hat mir gezeigt, wie viel man mit reinem C umsetzen kann und wo die Grenzen des Terminals liegen. Besonders die Arbeit mit Zeigern und Arrays war lehrreich. Durch den erfolgreichen Umstieg auf Raylib habe ich gelernt, wie ich eine schöne grafische Oberfläche mit gutem UI erstellen kann.
Im weiteren Verlauf des Projekts habe ich außerdem eine Web-Integration mithilfe von Emscripten umgesetzt, sodass das Spiel nicht mehr nur als lokale Anwendung läuft, sondern direkt im Browser spielbar ist. Dabei habe ich verstanden, wie aus nativen C/C++-Programmen durch WebAssembly eine Brücke zum Web entsteht und welche Anpassungen dafür notwendig sind. Besonders interessant war es, mit den Build-Prozessen und der Kompilierung für unterschiedliche Zielplattformen zu arbeiten, da sich dadurch viele neue technische Zusammenhänge erschließen.
Insgesamt habe ich durch dieses Projekt nicht nur meine Programmierkenntnisse in C deutlich vertieft, sondern auch gelernt, wie wichtig eine saubere Strukturierung des Codes ist, wenn Projekte größer und komplexer werden. Außerdem habe ich ein besseres Verständnis dafür entwickelt, wie Spiele-Logik, Rendering und Benutzerinteraktion zusammenwirken. Die Kombination aus klassischer Softwareentwicklung und moderner Web-Technologie hat mir gezeigt, wie flexibel heutige Entwicklungswerkzeuge sind und welche Möglichkeiten sich daraus ergeben.
Versionshistorie