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 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 14:31:38 +02:00
co-authored by Claude Fable 5
parent 68be969e0d
commit bca944810e
2 changed files with 53 additions and 8 deletions
+20
View File
@@ -1711,3 +1711,23 @@ eingebauter Cheat-Mode ;-).
E2E verifiziert: Karte -> 2x Right (Figur laeuft) -> W1L3 gestartet E2E verifiziert: Karte -> 2x Right (Figur laeuft) -> W1L3 gestartet
(generischer Spawn) -> ESC -> Karte (Position gemerkt) -> Left -> W1L2 (generischer Spawn) -> ESC -> Karte (Position gemerkt) -> Left -> W1L2
gestartet -> ESC/ESC/QUIT rc=0. --once exit 0. 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).
+33 -8
View File
@@ -27,7 +27,16 @@ from . import intro
# Mini-Kopf-Sprite je Charakter (KARTE4=Tony, 5=Smacks, 6=Toucan, 7=Coco) # Mini-Kopf-Sprite je Charakter (KARTE4=Tony, 5=Smacks, 6=Toucan, 7=Coco)
HEAD_SPRITE = {'TONY': 'KARTE4', 'SMACKS': 'KARTE5', 'TOUCAN': 'KARTE6', 'COCO': 'KARTE7'} HEAD_SPRITE = {'TONY': 'KARTE4', 'SMACKS': 'KARTE5', 'TOUCAN': 'KARTE6', 'COCO': 'KARTE7'}
STEP_SECONDS = 0.18 # Lauftempo der Kartenfigur pro Wegpunkt 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): def parse_worldmap(exe_path):
@@ -110,6 +119,13 @@ class WorldMap:
f'Fallback nur Level 1', file=sys.stderr) f'Fallback nur Level 1', file=sys.stderr)
self.segments = [dict(waypoints=[(113, 35)], stand=(113, 35), label=(108, 51))] self.segments = [dict(waypoints=[(113, 35)], stand=(113, 35), label=(108, 51))]
self.names = ['W1L1'] 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_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_big_off = intro.make_border_bg_transparent(assets.pcc_surface('KARTE2'))
self.dot_small = intro.make_border_bg_transparent(assets.pcc_surface('KARTE3')) 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): def draw(self, canvas, char, t, walk_pos=None):
canvas.blit(self.karte, (0, 0)) 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): for i, seg in enumerate(self.segments):
if seg['label'] is None: if seg['label'] is None:
continue continue
lx, ly = seg['label'] lx, ly = seg['label']
if i == self.current: if i == self.current and walk_pos is None:
dot = self.dot_big_on if int(t / BLINK_SECONDS) % 2 == 0 else self.dot_big_off # 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: else:
dot = self.dot_small dot = self.dot_small
canvas.blit(dot, (lx - dot.get_width() // 2, ly - dot.get_height() // 2)) canvas.blit(dot, (lx - dot.get_width() // 2, ly - dot.get_height() // 2))
# Spielfigur-Kopf # waehrend des Laufens: Kopf entlang des Pfads
px, py = walk_pos if walk_pos else self.segments[self.current]['stand'] if walk_pos is not None:
head = self.heads.get(char, self.heads['TONY']) px, py = walk_pos
canvas.blit(head, (px - head.get_width() // 2, py - head.get_height())) canvas.blit(head, (px - head.get_width() // 2, py - head.get_height()))
def run_worldmap(clock, assets, menu_assets, char='TONY', state={}): def run_worldmap(clock, assets, menu_assets, char='TONY', state={}):