v1.1: Stufen Easy/Normal/Hard mit Auswahlmenü (Hard = altes Tempo). Koffer behalten beim Drehen ihre Textur. Name/Punkteliste entfernt, nur Stufe + Prozent. Endlos: Ergebnis -> "Nochmals?" -> Stufenauswahl, Ende nur per Esc. storage.py und net.py gelöscht, 48 Tests.

This commit is contained in:
Project Bridge committed 2026-11-01 10:48:52 +00:00
1 parent de550e1d4d
commit d970185e75
15 files changed
+613 -342

No files matched your search

+39 -44
View File
@@ -1,8 +1,8 @@
# Habegger Trailer Load
Kofferlager-Spiel für Messe-/Eventbetrieb: Koffer laufen von rechts ein und
müssen im Auflieger möglichst dicht gestapelt werden. Ziel ist eine hohe
Beladung in Prozent.
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
@@ -27,68 +27,67 @@ 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).
Optionen:
| Option | Bedeutung |
| --- | --- |
| `--fullscreen` | Vollbild starten (F11 schaltet jederzeit um) |
| `--name "Anna"` | Spielername setzen (sonst der zuletzt gespeicherte) |
| `--seed 42` | feste Zufallsfolge, reproduzierbare Koffer-Sequenzen |
| `--smoke 10` | Selbsttest: bestätigt das Intro automatisch, spielt 10 s ohne Eingaben und beendet sich |
| `--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) |
| --- | --- | --- |
| Einrasten an der Barriere | `Space` / `Enter` | A |
| 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 |
| Spiel beenden | `Esc` | B |
| Beenden | `Esc` | B |
| Vollbild umschalten | `F11` | – |
Stick und D-Pad werden beide ausgewertet, Controller-Hotplug funktioniert
(der Name des erkannten Controllers steht beim Start im Terminal).
Ein gedrehter Koffer behält seine Grafik – er wird nur um 90° gedreht
gezeichnet, nie durch eine andere Textur ersetzt.
## Projektstruktur
```
main.py Einstiegspunkt (Fenster, Hauptschleife, CLI)
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, Tempi, Farben, Texte, Pfade
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 und Einlaufbewegung
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 des Spiels
storage.py Laufzeitdaten (letzter Spielername)
net.py optionaler Punkte-Upload
tests/test_logic.py 35 Tests (ohne Fenster)
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)
runtime/ Laufzeitdaten (nicht versioniert)
```
## Konfiguration
Alle Werte stehen in `loader_game/config.py` – Auflösung, Bänder, Auflieger,
Tempo, Farben, Texte. Gezeichnet wird immer in der virtuellen Auflösung
1920×1080; `pygame.SCALED` skaliert automatisch auf die tatsächliche
Fenstergrösse (Retina, 1440×900, 4K …).
Punkte-Upload (standardmässig aus):
```bash
export HAG_SCORE_URL="https://…/api/submit_points.php"
export HAG_SCORE_API_KEY="…"
```
Zugangsdaten gehören in die Umgebung, **nicht** in den Quellcode.
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
@@ -109,23 +108,19 @@ Ungültige Zeilen werden beim Start mit Meldung übersprungen.
.venv/bin/python -m unittest discover -s tests -v
```
Getestet werden Sequenz-Parsing, Layout-Invarianten, Kofferbewegung,
Stapelregeln, komplette Spieldurchläufe (bis Spielende) und die
Laufzeitdaten. Kein Fenster, kein Ton nötig.
## Laufzeitdaten
`runtime/` (in `.gitignore`): zuletzt verwendeter Spielername. Per
`HAG_RUNTIME_DIR` umlenkbar (nutzen die Tests).
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 – ebenfalls in `.gitignore`,
also **nicht** versioniert. Details: `old_version/FROZEN.md`.
`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) – ersetzt QR-Scanner und `last_user.txt`.
2. Mehrere Durchgänge ohne Neustart des Programms (zurück zur Namenseingabe).
3. Entscheiden, ob und wohin die Punkte gesendet werden.
Tastatur) – falls wieder eine Personalisierung gewünscht ist.
2. Entscheiden, ob und wohin Ergebnisse gesendet werden (Punkteliste ist
derzeit bewusst nicht vorhanden).