LEVEL 1 SPIELBAR: game/level.py -- Tiles, Kamera, Tony-Physik, HUD, Musik

Weltkarte: SPACE startet Level 1 (Original-Verhalten per DOSBox-Referenz:
Return tut dort nichts, kein sichtbarer Level-Cursor am Spielstart).

Level 1 = W1L1.MAP -- per Template-Matching des DOSBox-Gameplay-Screenshots
gegen die gerenderten Maps identifiziert (W1L0 ist NICHT Level 1).

game/level.py:
- Level: MAP+ICO+Weltpalette laden, komplette Map einmalig vorrendern,
  Kamera blittet 320x176-Ausschnitt (HUD 320x24 darunter, wie Original).
- Kollision: MAP-ctype Bit 32 = solide (40=Boden, 32=Fuellung; empirisch
  an der Spawn-Plattform verifiziert).
- Tony: TONY.BOB (53 Frames; 8-Phasen-Gehzyklus, gerade=links/ungerade=
  rechts), AABB-Physik gegen das Tile-Grid, laufen/springen/ducken,
  Fusspunkt-basiert. Physikwerte v1 nach Gefuehl (Feinschliff nach Test).
- HUD-Nachbildung (Keks/Item/Score/Herzen/Leben/Uhr 10:00-Countdown) mit
  FON_1B-Ziffern; GAMEBAR-Icons geladen (Original-Ziffern-Palette unklar).
- Levelmusik: ONGAME2 Song 0 als v1-ANNAHME (nach Gehoer korrigieren, wie
  beim Factor5-Sound); wird im Audio-Preload mitgerendert.
- ESC -> zurueck zur Karte (Titelmusik loopt wieder), Fenster-X -> Ende.

Verifiziert: E2E unter Xvfb mit gehaltenen XTEST-Tasten -- laufen (Kamera
scrollt), springen, Plattformkante runterfallen, unterm Brueckenbogen
zurueck, ESC->Karte->Menue->QUIT rc=0. Level-Standbild deckungsgleich zur
DOSBox-Referenz. --once-Regression exit 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
duffyduck
2026-07-25 01:17:44 +02:00
co-authored by Claude Fable 5
parent 4517efbdf8
commit 973e290cf6
5 changed files with 420 additions and 7 deletions
+22 -1
View File
@@ -550,10 +550,13 @@ def preload_all_audio(clock, assets):
# (DOSBox-Messung ~4.8s; Stefans Erinnerung "ca. 5 Sekunden") und stoppt
# den Sound beim Wechsel. render_tfmx blendet das Ende sauber aus (600ms
# Fade), scene_factor5 haelt den Screen genau Songlaenge.
# ONGAME2 (Song 0) = Levelmusik-Annahme fuer Level 1 (~123s Loop) --
# einmalig hier mitrendern, damit der Levelstart nie blockiert.
jobs = [
(('TITEL2', 0), 'Rauser-Sound', 5.0),
(('TITEL2', 1), 'Factor5-Sound', 2.6),
(('TITEL', None), 'Titelmusik', None),
(('ONGAME2', None), 'Levelmusik', None),
]
audio_paths = {}
for key, label, tail in jobs:
@@ -953,7 +956,18 @@ def main():
wait_or_skip(clock, 3.0, lambda _t: _blit_title(title_img))
else:
from . import menu as menu_mod
from . import level as level_mod
m = menu_mod.MenuAssets(assets)
def play_title_music():
path = audio_paths.get(('TITEL', None))
if pygame.mixer.get_init() and path:
try:
pygame.mixer.music.load(path)
pygame.mixer.music.play(-1)
except Exception:
pass
state = 'title'
while state not in ('quit',):
if state == 'title':
@@ -963,7 +977,14 @@ def main():
state = {'start': 'map', 'title': 'title'}.get(r, 'quit')
elif state == 'map':
r = menu_mod.run_worldmap(clock, m)
state = 'menu' if r == 'menu' else 'quit'
state = {'level': 'level', 'menu': 'menu'}.get(r, 'quit')
elif state == 'level':
r = level_mod.run_level(clock, assets, audio_paths)
if r == 'map':
play_title_music() # Karte/Menue laufen mit Titelmusik
state = 'map'
else:
state = 'quit'
if pygame.mixer.get_init():
pygame.mixer.music.stop()