"""Vorspann: Anleitungsbild und Startsequenz (Ampel + Reissverschluss). Bewusst zwei getrennte Bausteine, damit die Reihenfolge im Hauptprogramm eindeutig ist: **Anleitung → Moduswahl → Startsequenz → Spiel**. """ from __future__ import annotations import pygame from . import config, scene from .input_map import Action class Tutorial: """Zeigt das Anleitungsbild und wartet auf A / Space. Kommt vor jeder Runde – auch nach einem Ergebnis. """ def __init__(self, assets) -> None: self.assets = assets self.done = assets.instruction is None def handle(self, action: Action) -> None: if action is Action.PRIMARY: self.done = True def update(self, dt: float) -> bool: return self.done def draw(self, surface: pygame.Surface) -> None: if self.assets.instruction is not None: surface.blit(self.assets.instruction, (0, 0)) return scene.draw_top_bar(surface, self.assets, 0.0) scene.draw_background(surface, self.assets) scene.clear_bottom_bar(surface) class StartSequence: """Ampel (rot/gelb/grün) und Reissverschluss, der den Auflieger öffnet.""" def __init__(self, assets) -> None: self.assets = assets self.timer = 0.0 self.dot_index = 0 self.finished = False self.assets.play("beep1") def handle(self, action: Action) -> None: """Während der Startsequenz wird keine Eingabe gebraucht.""" def update(self, dt: float) -> bool: self.timer += dt if not self.finished: index = int(self.timer // config.INTRO_DOT_DELAY) if index >= len(config.INTRO_DOT_COLORS): self.finished = True 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 return self.timer >= config.INTRO_ZIP_DURATION def draw(self, surface: pygame.Surface) -> None: scene.draw_top_bar(surface, self.assets, 0.0) scene.draw_background(surface, self.assets) scene.clear_bottom_bar(surface) if not self.finished: 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, ) else: duration = config.INTRO_ZIP_DURATION or 1.0 progress = min(1.0, self.timer / duration) width = int(config.TRAILER_WIDTH * progress) pygame.draw.rect( surface, config.COLOR_TRAILER, (config.TRAILER_X, config.TRAILER_Y, width, config.TRAILER_HEIGHT), )