HUD final: GAMEBAR.PCC pur (weisse Boxen), Original-Ziffern, 6 Herzen

Stefans Korrektur: Box-Innenflaechen sind im Original WEISS (die Grafik
hatte es schon richtig -- Dunkelrot-Fuellung entfernt, Grafik-":" damit
nativ sichtbar). Zahlen jetzt in der Original-HUD-Font: GAMEBAR.BOB-
Ziffern (7x13), gerendert mit der GAMEBAR.PCC-Palette -> sattes Rot mit
dunkler Umrandung, gleiche Farbe wie der Doppelpunkt. Herzen: 6 Stueck im
3x2-Grid (Original-Screenshot), Start/Reset auf 6.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 11:46:46 +02:00
co-authored by Claude Fable 5
parent 6c3d6ea7a7
commit 54e950141b
2 changed files with 50 additions and 44 deletions
+18
View File
@@ -1535,3 +1535,21 @@ Smacks unter der Bruecke stoesst korrekt an die Decke) + E2E rc=0 + --once ok.
Verifiziert: Slope-Drop pixelgenau, Plateau-Aufstieg + Weiterlauf, Wand- Verifiziert: Slope-Drop pixelgenau, Plateau-Aufstieg + Weiterlauf, Wand-
Integritaet, Smacks idle=12, --once exit 0, E2E rc=0. Integritaet, Smacks idle=12, --once exit 0, E2E rc=0.
## 25.07.2026 (6) -- HUD final: GAMEBAR pur (weisse Boxen) + Original-Ziffern
Stefans Korrektur zur letzten Runde: die Box-Innenflaechen sind im Original
WEISS (genau wie in der GAMEBAR.PCC-Grafik -- die dunkelroten Boxen im
frueheren DOSBox-Screenshot waren wohl ein Farb-Artefakt), die Zahlen sind
ROT in der Original-HUD-Font, und es sind 6 HERZEN (3x2).
Loesung: GAMEBAR.PCC wird jetzt PUR geblittet (keine Fuellung mehr, der
Grafik-":" ist auf weiss natuerlich sichtbar). Die Zahlen sind die
GAMEBAR.BOB-Ziffern (7x13) gerendert mit der GAMEBAR.PCC-PALETTE -- damit
sind sie sattrot mit dunkler Umrandung, exakt wie der ":" (mit der
bob-Regel-Palette waren sie braeunlich; Stefan: "koennte sogar braun sein"
-- die PCC-Palette ist die konsistente Wahl, Umschalten waere 1 Zeile).
Herzen: 6 (3x2-Grid, Frame 10 mit PCC-Palette), leere Plaetze bleiben weiss.
hearts-Start/-Reset = 6.
HUD-Render deckungsgleich mit Stefans Original-Screenshot. --once/E2E ok.
+32 -44
View File
@@ -423,34 +423,20 @@ class Hud:
[57-99 Icon+Kekse][105-154 Item][160-210 Score][216-248 Herzen 2x2] [57-99 Icon+Kekse][105-154 Item][160-210 Score][216-248 Herzen 2x2]
[254-280 Kopf+Leben][286-315 Uhr].''' [254-280 Kopf+Leben][286-315 Uhr].'''
BOX_FILL = (146, 10, 10)
def __init__(self, assets): def __init__(self, assets):
from .menu import BitmapFont, _mapping_from_rows from .formats import load_pcc
container = assets.container container = assets.container
# Die Boxen der GAMEBAR.PCC bleiben WEISS (die Grafik hat das schon
# richtig -- Stefans Korrektur); Ziffern/Herzen kommen aus
# GAMEBAR.BOB, gerendert mit der GAMEBAR.PCC-PALETTE (damit sind die
# Ziffern ROT mit dunkler Umrandung wie im Original -- mit der
# bob-Regel-Palette waren sie braun).
_, _, _, gb_pal = load_pcc(container.entries['GAMEBAR.PCC'])
frames = parse_bob(container.entries['GAMEBAR.BOB']) frames = parse_bob(container.entries['GAMEBAR.BOB'])
palette = get_bob_palette(container.entries, 'GAMEBAR') self.icons = _frames_to_surfaces(frames, gb_pal)
self.icons = _frames_to_surfaces(frames, palette) self.digits = self.icons[0:10] # 7x13, rot
self.heart_full = self.icons[10] self.heart_full = self.icons[10]
self.font = BitmapFont(assets.pcc_surface('FON_1B'), 9, 7, self.bar = assets.pcc_surface('GAMEBAR').convert()
_mapping_from_rows(['1234567890;:!"%/()=?,.-\x7f#']),
spacing=8)
# GAMEBAR.PCC vorbereiten: Innenflaechen der 6 Boxen dunkelrot,
# der Grafik-":" (Uhr-Box) gelb wie die Ziffern.
bar = assets.pcc_surface('GAMEBAR').convert()
import pygame.surfarray as sa
arr = sa.pixels3d(bar)
w = arr.shape[0]
for x in range(56, w):
col = arr[x]
for y in range(col.shape[0]):
r, g, b = col[y]
if r > 200 and g > 200 and b > 200:
col[y] = self.BOX_FILL
elif 292 <= x <= 302 and r > 150 and g < 100:
col[y] = (255, 222, 0) # ":"-Punkte der Uhr
del arr
self.bar = bar
self.item_icons = {n: intro.make_border_bg_transparent(assets.pcc_surface(n)) self.item_icons = {n: intro.make_border_bg_transparent(assets.pcc_surface(n))
for n in ('ITE0', 'ITE1', 'ITE2', 'ITE3')} for n in ('ITE0', 'ITE1', 'ITE2', 'ITE3')}
self.heads_small = [] self.heads_small = []
@@ -458,32 +444,34 @@ class Hud:
head = intro.make_border_bg_transparent(assets.pcc_surface(f'WECH_{i}')) head = intro.make_border_bg_transparent(assets.pcc_surface(f'WECH_{i}'))
self.heads_small.append(pygame.transform.smoothscale(head, (17, 16))) self.heads_small.append(pygame.transform.smoothscale(head, (17, 16)))
def _text(self, canvas, x, y, text): def _number(self, canvas, x, y, value, width):
canvas.blit(self.font.render(text, outline=(0, 0, 0)), (x, y)) s = str(max(0, int(value))).rjust(width, '0')[-width:]
for i, ch in enumerate(s):
canvas.blit(self.digits[int(ch)], (x + i * 8, y))
def draw(self, canvas, y0, char_def, cookies, score, hearts, lives, time_left): def draw(self, canvas, y0, char_def, cookies, score, hearts, lives, time_left):
canvas.blit(self.bar, (0, y0)) canvas.blit(self.bar, (0, y0))
text_y = y0 + 9 num_y = y0 + 6
# Box 1: Cerealien-Icon des aktiven Charakters + Keks-Zaehler # Box 1 (57-99): Cerealien-Icon des aktiven Charakters + Keks-Zaehler
icon = self.item_icons.get(char_def['item_icon']) icon = self.item_icons.get(char_def['item_icon'])
if icon: if icon:
canvas.blit(icon, (59, y0 + 4)) canvas.blit(icon, (58, y0 + 4))
self._text(canvas, 76, text_y, f'{cookies:03d}') self._number(canvas, 75, num_y, cookies, 3)
# Box 2 (105-154): Item -- noch leer # Box 2 (105-154): Item -- noch leer
# Box 3: Score # Box 3 (160-210): Score
self._text(canvas, 161, text_y, f'{score:06d}') self._number(canvas, 161, num_y, score, 6)
# Box 4: Herzen 2x2 (leere Plaetze bleiben dunkel) # Box 4 (216-248): Herzen, 3x2-Grid, max 6 (Original-Screenshot);
for i in range(min(hearts, 4)): # leere Plaetze bleiben weiss
canvas.blit(self.heart_full, (221 + (i % 2) * 11, y0 + 4 + (i // 2) * 9)) for i in range(min(hearts, 6)):
# Box 5: Charakter-Kopf (immer die gewaehlte Figur) + Leben canvas.blit(self.heart_full, (218 + (i % 3) * 10, y0 + 4 + (i // 3) * 9))
# Box 5 (254-280): Charakter-Kopf (immer die gewaehlte Figur) + Leben
canvas.blit(self.heads_small[char_def['head_index']], (254, y0 + 4)) canvas.blit(self.heads_small[char_def['head_index']], (254, y0 + 4))
self._text(canvas, 272, text_y, str(lives)) self._number(canvas, 272, num_y, lives, 1)
# Box 6: Uhr (der Grafik-":" ist rot auf dunkelrot kaum sichtbar -- # Box 6 (286-315): Uhr -- der ":" ist Teil der Grafik (auf weiss
# eigener gelber ":" per Font drueber) # sichtbar, Stefans Bestaetigung)
m, s = divmod(max(0, int(time_left)), 60) m, s = divmod(max(0, int(time_left)), 60)
self._text(canvas, 288, text_y, str(m)) self._number(canvas, 288, num_y, m, 1)
self._text(canvas, 294, text_y, ':') self._number(canvas, 300, num_y, s, 2)
self._text(canvas, 301, text_y, f'{s:02d}')
def run_character_select(clock, assets, available, current): def run_character_select(clock, assets, available, current):
@@ -560,7 +548,7 @@ def run_level(clock, assets, audio_paths, map_name='W1L1'):
start = time.monotonic() start = time.monotonic()
map_w_px = level.width * TILE map_w_px = level.width * TILE
map_h_px = level.height * TILE map_h_px = level.height * TILE
hearts, lives = 4, 3 hearts, lives = 6, 3 # 6 Herzen (3x2) -- Original-Screenshot
water_t = 0.0 water_t = 0.0
while True: while True:
@@ -597,7 +585,7 @@ def run_level(clock, assets, audio_paths, map_name='W1L1'):
hearts -= 1 hearts -= 1
if hearts <= 0: if hearts <= 0:
lives -= 1 lives -= 1
hearts = 4 hearts = 6
player.x, player.y = spawn_px player.x, player.y = spawn_px
player.vy = 0.0 player.vy = 0.0
if lives <= 0: if lives <= 0: