# Habegger Trailer Load Kofferlager-Spiel für Messe-/Eventbetrieb: Koffer laufen von rechts ein und müssen im Auflieger möglichst dicht gestapelt werden. Angezeigt wird am Ende die Stufe und die erreichte Beladung in Prozent. Neu aufgesetzt für macOS (Apple Silicon) mit Controller-Unterstützung. Die Analyse des Altstands und die Liste der behobenen Fehler stehen in [`docs/ANALYSE.md`](docs/ANALYSE.md). ## Voraussetzungen * Python 3.10 oder neuer (getestet: 3.12) * macOS oder Linux – sonst nichts. `pygame` bringt SDL2 selbst mit, Kamera-, Brew- oder Systembibliotheken werden **nicht** gebraucht. ## Start ```bash ./run.sh # Fenster ./run.sh --fullscreen # Vollbild (Eventbetrieb) ``` `run.sh` legt beim ersten Start `.venv/` an und installiert `requirements.txt` automatisch. Ändert sich `requirements.txt`, wird neu installiert. Auf macOS lässt sich das Spiel auch per Doppelklick auf **`run.command`** starten (beim ersten Mal ggf. Rechtsklick → Öffnen wegen Gatekeeper). | Option | Bedeutung | | --- | --- | | `--fullscreen` | Vollbild starten (F11 schaltet jederzeit um) | | `--seed 42` | feste Zufallsfolge, reproduzierbare Koffer-Sequenzen | | `--smoke 10` | Selbsttest: spielt 10 s ohne Eingaben und beendet sich | ## Ablauf 1. **Tutorialbild** (nur beim Programmstart) – weiter mit A / Space 2. **Stufenauswahl**: Easy / Normal / Hard (Hard = Tempo des Altstands) 3. **Ampel-Start** (rot/gelb/grün + Reissverschluss), dann läuft die Runde 4. **Ergebnis**: Stufe und Beladung in Prozent, „Nochmals?" → A startet neu bei der Stufenauswahl Beendet wird ausschliesslich mit **Esc** (Controller: B). ## Steuerung | Aktion | Tastatur | Controller (Xbox-Layout) | | --- | --- | --- | | Stufe wählen | `←` / `→` | D-Pad links/rechts | | Bestätigen / Einrasten an der Barriere | `Space` / `Enter` | A | | Koffer drehen (wenn er passt) | `←` | X / D-Pad links | | Auf einen Koffer obendrauf setzen | `↑` | Y / D-Pad hoch | | Beenden | `Esc` | B | | Vollbild umschalten | `F11` | – | Ein gedrehter Koffer behält seine Grafik – er wird nur um 90° gedreht gezeichnet, nie durch eine andere Textur ersetzt. ## Projektstruktur ``` main.py Einstiegspunkt (Phasen: Intro → Menü → Runde) run.sh / run.command Start inkl. venv + Installation requirements.txt pygame case_sequences.txt Koffersequenzen (Datenbestand) loader_game/ config.py Masse, Farben, Texte, Pfade difficulty.py Stufen Easy/Normal/Hard (Tempo) assets.py Bilder/Sounds/Fonts laden und cachen sequences.py Einlesen und Validieren der Sequenzdatei case.py Koffer: Geometrie, Textur, Bewegung trailer.py Stapelregeln im Auflieger (reine Logik) input_map.py Tastatur/Controller → Action scene.py Zeichnen menu.py Stufenauswahl intro.py Tutorialbild, Ampel, Reissverschluss game.py Zustandsmaschine einer Runde tests/test_logic.py 48 Tests (ohne Fenster) docs/ANALYSE.md Analyse Altstand + Fehlerliste old_version/ eingefrorener Altstand (nicht versioniert) ``` ## Konfiguration Alle Werte stehen in `loader_game/config.py` (Layout, Farben, Texte, Tempo der Animationen) und `loader_game/difficulty.py` (Einlaufgeschwindigkeit der drei Stufen). Gezeichnet wird immer in der virtuellen Auflösung 1920×1080; `pygame.SCALED` skaliert automatisch auf die tatsächliche Fenstergrösse (Retina, 1440×900, 4K …). ## Sequenzdatei `case_sequences.txt`: Sequenzen durch Leerzeilen getrennt, pro Zeile ein Koffer als `breite,höhe,rotiert` in Einheiten von 100×100 Pixeln. `rotiert=True` dreht den Koffer beim Einlaufen um 90°. ``` 3,1,False 1,2,True # effektiv 2 Einheiten breit, 1 hoch ``` Ungültige Zeilen werden beim Start mit Meldung übersprungen. ## Tests ```bash .venv/bin/python -m unittest discover -s tests -v ``` Getestet werden Sequenz-Parsing, Layout-Invarianten, Kofferbewegung (inkl. Stufen-Tempo), Stapelregeln, Menü-Navigation, komplette Spieldurchläufe bis zum Ergebnis sowie das Rendern von Intro, Menü, Spiel und Ergebnis. Kein Fenster, kein Ton nötig. ## Eingefrorener Altstand `old_version/` enthält die Dateien vor dem Umbau – in `.gitignore`, also **nicht** versioniert. Details: `old_version/FROZEN.md`. ## Nächste Schritte 1. Namenseingabe direkt am Controller (Buchstabe für Buchstabe, alternativ Tastatur) – falls wieder eine Personalisierung gewünscht ist. 2. Entscheiden, ob und wohin Ergebnisse gesendet werden (Punkteliste ist derzeit bewusst nicht vorhanden).