Memory-Spiel
Ein sorgfältig umgesetztes Memory-Kartenspiel als Lernprojekt im Apps Team: ein Next.js / React-Frontend in TypeScript, angebunden an ein NestJS-Backend, mit Live-Timer, Rangliste, Light-/Dark-Theme und einer verspielten Horror-Note.
Überblick
Die Aufgabe war ein klassisches Memory-Spiel: ein 4×4-Raster mit 16 Karten (8 einzigartige Bilder, jeweils dupliziert und gemischt). Spielende decken zwei Karten gleichzeitig auf; passende Paare bleiben offen, nicht passende werden nach kurzer Verzögerung wieder zugedeckt. Sind alle Paare gefunden, trägt man seine Zeit in die Rangliste ein. Über den geforderten Umfang hinaus habe ich ein Light-/Dark-Theme, Hintergrundmusik und Soundeffekte sowie einen zeitgesteuerten „Grusel-Modus“ mit Endszene ergänzt.
Hauptfunktionen
Spiellogik mit React Hooks
Das gesamte Spielbrett lebt im React-State über useState, useEffect und useRef: Aufdecken, Match-Prüfung, Sperren des Bretts und Erkennen der Gewinnbedingung.
Timer & Wertung
Ein Live-Timer startet beim ersten Aufdecken; die Endzeit wird zum Score, der ans Backend gesendet und in einer nach Bestzeit sortierten Rangliste angezeigt wird.
Backend-Anbindung
Kartenbilder und Scores werden über axios von einer NestJS-API geladen bzw. an sie gesendet: die Basis-URL kommt aus einer Umgebungsvariable.
Light- / Dark-Theme
Die Oberfläche reagiert auf die Farbpräferenz des Betriebssystems und tauscht Kartenmotive, Hintergründe und Musik je Modus aus.
Sound & Atmosphäre
Hintergrundtracks, Match-/Gewinn-Sounds und eine zeitgesteuerte „Sonic.exe / Mario.exe“-Wendung mit Video-Endszene.
Saubere Konfiguration & CI
Secrets bleiben dank NEXT_PUBLIC_*-Umgebungsvariablen aus dem Code heraus; GitLab CI mit Secret Detection.
Entstehung
- Grundgerüst: leere NestJS-App und ein Karten-Raster mit Hover-Animation und Titel erstellt.
- Verdrahtung: Frontend und Backend verbunden, danach die Klick-/Aufdeck-Logik ergänzt.
- Gameplay: Hintergrundkarten, einen funktionierenden Timer und die Match-Logik gebaut.
- Rangliste: den Score ans Backend angebunden und eine sortierte Rangliste gerendert.
- Feinschliff: das Spiel fertiggestellt und die Backend-URL in eine Umgebungsvariable ausgelagert.
- Atmosphäre: Themen-Sounds und die Endszene ergänzt; nebenbei einen Merge-Konflikt gelöst.
Tägliche Commits und Feature-Branches hielten den gesamten Fortschritt nachvollziehbar.
Was ich gelernt habe
Dieses Projekt hat meine Fähigkeit geschärft, nicht-trivialen UI-State in React mit Hooks zu modellieren, Komponenten in TypeScript typisiert zu halten, ein REST-Backend sauber anzubinden und Konfiguration über Umgebungsvariablen auszulagern. Ausserdem hat es eine disziplinierte Versionierung gefestigt: kleine, aussagekräftige Commits und das Lösen von Konflikten auf einem Feature-Branch.