From bca944810ee49b99236776166af37a0cebbbb2d3 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sat, 25 Jul 2026 14:31:38 +0200 Subject: [PATCH] Weltkarte: y-Flip der Binary-Koordinaten + Original-Blinken (Punkt<->Kopf) DOSBox-Nachmessung des blinkenden Level-1-Markers (real (59,153) vs Binary-Label (53,56)): die Binary-y-Achse ist geflippt (screen_y=209-y). Alle Pfade/Punkte jetzt an den Original-Positionen (W1 Wald unten, W2/W3 Berge/Schloss -- deckungsgleich mit Stefans Original-/Netz-Screenshots, Kopf-am-Teich = W1L7). An der aktuellen Position wechseln Punkt und Mini-Kopf im 0.5s-Rhythmus (Original-Verhalten laut Frame-Diff, die Referenzbilder zeigen jeweils eine Phase). Co-Authored-By: Claude Fable 5 --- NOTES.md | 20 ++++++++++++++++++++ game/worldmap.py | 41 +++++++++++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/NOTES.md b/NOTES.md index 4909058..6ffa1f4 100644 --- a/NOTES.md +++ b/NOTES.md @@ -1711,3 +1711,23 @@ eingebauter Cheat-Mode ;-). E2E verifiziert: Karte -> 2x Right (Figur laeuft) -> W1L3 gestartet (generischer Spawn) -> ESC -> Karte (Position gemerkt) -> Left -> W1L2 gestartet -> ESC/ESC/QUIT rc=0. --once exit 0. + +## 25.07.2026 (14) -- Karten-Koordinaten korrigiert: y-Flip + Punkt/Kopf-Blinken + +Stefans Einwand (Original-Screenshots inkl. zweier Netzfunde mit +fortgeschrittenem Spielstand): nur Level-1-Punkt sichtbar, Position unten +beim Haus -- nicht in den Bergen wie bei uns. + +DOSBox-Nachmessung (Frame-Diff des blinkenden Markers): Level-1-Punkt real +bei (59,153); Binary-Label ist (53,56) => die Binary-y-Achse ist GEFLIPPT: +screen_y = 209 - y. Damit liegen W1 im Wald unten, W2/W3 in Bergen/ +Schloss oben -- deckungsgleich mit den Netz-Referenzen (Kopf am Teich in +Bild 1 = W1L7-Position!). + +Zweiter Fund aus der Diff-Region (13x15 = Kopfgroesse): an der aktuellen +Position wechseln PUNKT und MINI-KOPF im Blinkrhythmus (die Netzbilder +zeigen je eine Phase). Eingebaut. + +Noch offen (bewusst): nur-freigeschaltete-Punkte anzeigen kommt mit dem +Level-Abschluss-Feature; aktuell sind alle Punkte sichtbar/anwaehlbar +(Testphase). diff --git a/game/worldmap.py b/game/worldmap.py index d8864cb..8c9d47e 100644 --- a/game/worldmap.py +++ b/game/worldmap.py @@ -27,7 +27,16 @@ from . import intro # Mini-Kopf-Sprite je Charakter (KARTE4=Tony, 5=Smacks, 6=Toucan, 7=Coco) HEAD_SPRITE = {'TONY': 'KARTE4', 'SMACKS': 'KARTE5', 'TOUCAN': 'KARTE6', 'COCO': 'KARTE7'} STEP_SECONDS = 0.18 # Lauftempo der Kartenfigur pro Wegpunkt -BLINK_SECONDS = 0.5 # orange/blau-Wechsel des aktiven Punkts +BLINK_SECONDS = 0.5 # Blinkrhythmus der aktiven Position +# Die Binary-Koordinaten sind y-GEFLIPPT (DOSBox-Nachmessung 25.07.2026: +# Level-1-Punkt real bei (59,153), Binary-Label (53,56) -> screen_y = 209-y; +# damit liegen die fruehen Level im Wald unten und W2/W3 in Bergen/Schloss +# oben -- deckungsgleich mit Stefans Original-Screenshots). +MAP_Y_FLIP = 209 + + +def _tf(p): + return (p[0], MAP_Y_FLIP - p[1]) def parse_worldmap(exe_path): @@ -110,6 +119,13 @@ class WorldMap: f'Fallback nur Level 1', file=sys.stderr) self.segments = [dict(waypoints=[(113, 35)], stand=(113, 35), label=(108, 51))] self.names = ['W1L1'] + # Positionen ins Screen-System transformieren (y-Flip) + for seg in self.segments: + seg['waypoints'] = [_tf(p) for p in seg['waypoints']] + if seg['stand']: + seg['stand'] = _tf(seg['stand']) + if seg['label']: + seg['label'] = _tf(seg['label']) self.dot_big_on = intro.make_border_bg_transparent(assets.pcc_surface('KARTE0')) self.dot_big_off = intro.make_border_bg_transparent(assets.pcc_surface('KARTE2')) self.dot_small = intro.make_border_bg_transparent(assets.pcc_surface('KARTE3')) @@ -119,19 +135,28 @@ class WorldMap: def draw(self, canvas, char, t, walk_pos=None): canvas.blit(self.karte, (0, 0)) + head = self.heads.get(char, self.heads['TONY']) + head_phase = int(t / BLINK_SECONDS) % 2 == 0 for i, seg in enumerate(self.segments): if seg['label'] is None: continue lx, ly = seg['label'] - if i == self.current: - dot = self.dot_big_on if int(t / BLINK_SECONDS) % 2 == 0 else self.dot_big_off + if i == self.current and walk_pos is None: + # Original-Verhalten (Netz-Referenzbilder + DOSBox-Diff): + # an der aktuellen Position wechseln PUNKT und MINI-KOPF + if head_phase: + canvas.blit(head, (lx - head.get_width() // 2, ly - head.get_height() // 2)) + else: + canvas.blit(self.dot_big_on, + (lx - self.dot_big_on.get_width() // 2, + ly - self.dot_big_on.get_height() // 2)) else: dot = self.dot_small - canvas.blit(dot, (lx - dot.get_width() // 2, ly - dot.get_height() // 2)) - # Spielfigur-Kopf - px, py = walk_pos if walk_pos else self.segments[self.current]['stand'] - head = self.heads.get(char, self.heads['TONY']) - canvas.blit(head, (px - head.get_width() // 2, py - head.get_height())) + canvas.blit(dot, (lx - dot.get_width() // 2, ly - dot.get_height() // 2)) + # waehrend des Laufens: Kopf entlang des Pfads + if walk_pos is not None: + px, py = walk_pos + canvas.blit(head, (px - head.get_width() // 2, py - head.get_height())) def run_worldmap(clock, assets, menu_assets, char='TONY', state={}):