Wasser-Regeln (kein Ducken, 1.5s-Schaden), Schadens-Blinken, echte Peek-Frames

- Nicht-Schwimmer koennen im Wasser nicht mehr ducken.
- Herzverlust im Wasser alle 1.5s statt 5s.
- Nach Schaden blinkt die Figur 0.9s (Sichtbarkeits-Toggle; beim Tod
  deaktiviert, damit die Anim nicht unsichtbar haengt).
- Tuer-Reinschauen nutzt die echten Sprites: TONY 50 (Rueckenansicht),
  SMACKS 48 (Stefans Fund -- jeweils letzter Frame vor den Platzhaltern).

Verifiziert: Duck-Verbot im Wasser, Blink-Muster wechselt, --once exit 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 13:48:39 +02:00
co-authored by Claude Fable 5
parent 10c5a5b69c
commit 200fc6192d
2 changed files with 31 additions and 4 deletions
+14
View File
@@ -1607,3 +1607,17 @@ Tony-auf-Wasser+Frosties-Idle von Stefan als "sehr geil" abgenommen (kein Fix).
4. **Duck-Kamera-Flackern**: 0.2s-Grace-Period -- kurze Taste/on_ground-
Blips (X11-Autorepeat sendet Release/Press-Paare) setzen den
Halte-Timer nicht mehr zurueck.
## 25.07.2026 (10) -- sechste Feedback-Runde: Wasser-Regeln + Peek-Frames
- Ducken im Wasser fuer Nicht-Schwimmer verboten (Bounce + DOWN ergab
Duck-Pose auf der Oberflaeche).
- Wasser-Schaden: alle 1.5s statt 5s (Stefan: "5 Sekunden arg lang").
- Schadens-Blinken nach Herzverlust (0.9s Sichtbarkeits-Toggle ~6Hz --
ein eigenes Aua-Sprite gibt es in den BOBs nicht). Beim Todesstart wird
das Blinken deaktiviert (sonst waere die eingefrorene Blinkphase die
ganze Anim unsichtbar gewesen).
- TUER-REINSCHAU-Frames (Stefans Fund): TONY Frame 50 (Rueckenansicht!),
SMACKS Frame 48 -- jeweils der letzte Frame vor den Magenta-
Platzhaltern. Der als "gebueckt/kriechend" einsortierte Tony-50 war in
Wahrheit das Reinschauen.
+17 -4
View File
@@ -45,7 +45,7 @@ WALK_ANIM_FPS = 12.0
RUN_ANIM_FPS = 14.0
IDLE_ANIM_AFTER = 5.0 # Sekunden Stillstand bis zur Idle-Animation
IDLE_ANIM_FPS = 2.5
WATER_DAMAGE_EVERY = 5.0 # im Wasser: alle 5s ein Herz (Stefans Angabe)
WATER_DAMAGE_EVERY = 1.5 # im Wasser: alle 1.5s ein Herz (Stefan: 5s war arg lang)
SPAWN_ANIM_SECONDS = 1.1 # Start-Sprite beim Levelstart/Charakterwechsel
SPRITE_SINK = 4 # Fuesse sinken optisch in die Blaetter/Gras ein
# (Stefans "Figuren schweben ein paar Pixel")
@@ -74,7 +74,7 @@ CHAR_DEFS = {
idle_anim_r=[44, 46, 48], idle_anim_l=[45, 47, 49],
spawn_frame=22, # Arm nach oben gestreckt
death_frame=38, drop_frame=40, # erschrocken; fallendes HALSTUCH
peek_frame=34, # in die offene Tuer schauen
peek_frame=50, # in die Tuer reinschauen (Rueckenansicht -- Stefans Fund)
item_icon='ITE0', head_index=0,
),
'SMACKS': dict(
@@ -89,7 +89,7 @@ CHAR_DEFS = {
idle_anim_r=[31, 33, 35], idle_anim_l=[32, 34, 36],
spawn_frame=22, # Daumen-hoch-Geste
death_frame=26, drop_frame=29, # erschrocken; fallende KAPPE
peek_frame=20,
peek_frame=48, # Reinschau-Frame (letzter vor den Platzhaltern)
item_icon='ITE1', head_index=1,
),
'COCO': dict(
@@ -256,6 +256,7 @@ class Player:
self.idle_t = 0.0
self.spawn_t = 0.0 # Start-Sprite-Sequenz (Arm hoch/Daumen hoch)
self.force_frame = None # erzwungener Frame (Tuer-Peek, Tod)
self.hurt_t = 0.0 # Rest-Blinkzeit nach Schaden
self._grounded_before = False
self.set_character(char, pos)
@@ -277,6 +278,8 @@ class Player:
self.HITBOX_W, self.HITBOX_H)
def update(self, level, dt, keys):
if self.hurt_t > 0:
self.hurt_t -= dt
if self.spawn_t > 0:
self.spawn_t -= dt
# Eingabe bricht die Start-Pose sofort ab
@@ -285,7 +288,10 @@ class Player:
self.spawn_t = 0.0
in_water = level.in_water(self.y)
self.swimming = in_water and self.d['can_swim']
self.ducking = self.on_ground and not self.swimming and keys[pygame.K_DOWN]
# Ducken geht NICHT im Wasser (Stefans Regel -- auch nicht fuer
# Nicht-Schwimmer, die auf der Oberflaeche huepfen)
self.ducking = (self.on_ground and not self.swimming and not in_water
and keys[pygame.K_DOWN])
move = 0
if not self.ducking:
if keys[pygame.K_LEFT]:
@@ -437,6 +443,11 @@ class Player:
return self._pick('idle_r', 'idle_l')
def draw(self, screen, cam_x, cam_y):
# Schadens-Blinken: nach Herzverlust flackert die Figur kurz
# (klassisches Sichtbarkeits-Toggle -- ein eigenes "Aua"-Sprite gibt
# es in den BOBs nicht)
if self.hurt_t > 0 and int(self.hurt_t * 12) % 2 == 0:
return
i = self.current_frame_index()
surf = self.surfs[i] if i < len(self.surfs) else self.surfs[0]
screen.blit(surf, (int(self.x - surf.get_width() / 2 - cam_x),
@@ -668,9 +679,11 @@ def run_level(clock, assets, audio_paths, map_name='W1L1'):
if water_t >= WATER_DAMAGE_EVERY:
water_t = 0.0
hearts -= 1
player.hurt_t = 0.9 # Schadens-Blinken
if hearts <= 0 and player.d.get('death_frame') is not None:
# Tod-Animation starten: erschrockener Frame, Flug nach
# oben aus dem Bild, Tuch/Kappe faellt herunter
player.hurt_t = 0.0 # kein Blink-Toggle waehrend der Anim
player.force_frame = player.d['death_frame']
dying = dict(t=0.0, vy=-260.0,
drop_y=player.y - 40.0, drop_vy=-30.0)