Altstand nach old_version/ eingefroren (untracked). Monolith ersetzt durch main.py + Paket loader_game/. Neu: run.sh/run.command mit venv+requirements, .gitignore, docs/ANALYSE.md, 35 Tests. Secrets entfernt. Gelöscht: loader_game.py, qr_scan*.py, INSTALL_README.txt.

This commit is contained in:
Project Bridge committed 2026-11-01 10:25:13 +00:00
1 parent 6a2c891c3e
commit de550e1d4d
24 files changed
+2269 -1008

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
"""Tutorialbild, Ampel-Startsequenz und Reissverschluss-Effekt."""
from __future__ import annotations
import pygame
from . import config, scene
from .input_map import Action
class Intro:
"""Vorspann vor dem ersten Koffer.
Ablauf: Tutorialbild (wartet auf Bestätigung) → drei Punkte mit Ton →
Reissverschluss, der den Auflieger "öffnet".
"""
def __init__(self, assets) -> None:
self.assets = assets
self.phase = "instruction" if assets.instruction is not None else "countdown"
self.timer = 0.0
self.dot_index = 0
if self.phase == "countdown":
self._start_countdown()
# ------------------------------------------------------------------
def _start_countdown(self) -> None:
self.phase = "countdown"
self.timer = 0.0
self.dot_index = 0
self.assets.play("beep1")
def handle(self, action: Action) -> None:
if self.phase == "instruction" and action is Action.PRIMARY:
self._start_countdown()
def update(self, dt: float) -> bool:
"""Weiterrechnen; Rückgabe ``True``, wenn der Vorspann fertig ist."""
self.timer += dt
if self.phase == "countdown":
index = int(self.timer // config.INTRO_DOT_DELAY)
if index >= len(config.INTRO_DOT_COLORS):
self.phase = "zip"
self.timer = 0.0
self.assets.play("zip")
elif index != self.dot_index:
self.dot_index = index
self.assets.play(f"beep{index + 1}")
return False
if self.phase == "zip":
return self.timer >= config.INTRO_ZIP_DURATION
return False
# ------------------------------------------------------------------
def draw(self, surface: pygame.Surface) -> None:
if self.phase == "instruction":
surface.blit(self.assets.instruction, (0, 0))
return
scene.draw_top_bar(surface, self.assets, 0.0)
scene.draw_background(surface, self.assets)
scene.draw_bottom_bar(surface, self.assets, [])
if self.phase == "countdown":
if 0 <= self.dot_index < len(config.INTRO_DOT_COLORS):
pygame.draw.circle(
surface,
config.INTRO_DOT_COLORS[self.dot_index],
(
config.TRAILER_X + config.TRAILER_WIDTH // 2,
config.TRAILER_Y + config.TRAILER_HEIGHT // 2,
),
config.INTRO_DOT_RADIUS,
)
elif self.phase == "zip":
progress = min(1.0, self.timer / config.INTRO_ZIP_DURATION) if config.INTRO_ZIP_DURATION else 1.0
width = int(config.TRAILER_WIDTH * progress)
pygame.draw.rect(
surface,
config.COLOR_TRAILER,
(config.TRAILER_X, config.TRAILER_Y, width, config.TRAILER_HEIGHT),
)