v1.1: Stufen Easy/Normal/Hard mit Auswahlmenü (Hard = altes Tempo). Koffer behalten beim Drehen ihre Textur. Name/Punkteliste entfernt, nur Stufe + Prozent. Endlos: Ergebnis -> "Nochmals?" -> Stufenauswahl, Ende nur per Esc. storage.py und net.py gelöscht, 48 Tests.

This commit is contained in:
Project Bridge committed 2026-11-01 10:48:52 +00:00
1 parent de550e1d4d
commit d970185e75
15 files changed
+613 -342

No files matched your search

+100
View File
@@ -0,0 +1,100 @@
"""Startmenü: Schwierigkeitsstufe wählen (Easy / Normal / Hard)."""
from __future__ import annotations
import pygame
from . import config, scene
from .difficulty import DEFAULT_DIFFICULTY, DIFFICULTIES, Difficulty
from .input_map import Action
class DifficultyMenu:
"""Drei Kacheln, Auswahl mit ← / →, Start mit A / Space."""
def __init__(
self,
assets,
options: tuple[Difficulty, ...] = DIFFICULTIES,
selected: Difficulty = DEFAULT_DIFFICULTY,
) -> None:
self.assets = assets
self.options = list(options)
self.index = self.options.index(selected) if selected in self.options else 0
# ------------------------------------------------------------------
@property
def selected(self) -> Difficulty:
return self.options[self.index]
def handle(self, action: Action) -> Difficulty | None:
"""Rückgabe: gewählte Stufe, sobald bestätigt wurde – sonst ``None``."""
if action is Action.LEFT:
self.index = (self.index - 1) % len(self.options)
elif action is Action.RIGHT:
self.index = (self.index + 1) % len(self.options)
elif action is Action.PRIMARY:
return self.selected
return None
# ------------------------------------------------------------------
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)
scene.draw_dim(surface, 170)
font = self.assets.font
small = self.assets.font_small or font
title = font.render(config.MENU_TITLE, True, config.COLOR_WHITE)
surface.blit(
title,
(config.SCREEN_WIDTH // 2 - title.get_width() // 2, config.MENU_TOP - 110),
)
total_width = len(self.options) * config.MENU_BOX_WIDTH + (
len(self.options) - 1
) * config.MENU_BOX_GAP
x = (config.SCREEN_WIDTH - total_width) // 2
for index, difficulty in enumerate(self.options):
rect = pygame.Rect(
x, config.MENU_TOP, config.MENU_BOX_WIDTH, config.MENU_BOX_HEIGHT
)
active = index == self.index
pygame.draw.rect(
surface,
config.COLOR_MENU_BOX_ACTIVE if active else config.COLOR_MENU_BOX,
rect,
border_radius=14,
)
pygame.draw.rect(
surface,
config.COLOR_WHITE if active else config.COLOR_MENU_BORDER,
rect,
width=config.MENU_BOX_BORDER,
border_radius=14,
)
label = font.render(
difficulty.label, True, (0, 0, 0) if active else config.COLOR_WHITE
)
surface.blit(
label,
(
rect.centerx - label.get_width() // 2,
rect.centery - label.get_height() // 2,
),
)
x += config.MENU_BOX_WIDTH + config.MENU_BOX_GAP
hint = small.render(config.MENU_HINT, True, config.COLOR_WHITE)
hint_y = config.MENU_TOP + config.MENU_BOX_HEIGHT + 60
band = pygame.Rect(
config.SCREEN_WIDTH // 2 - hint.get_width() // 2 - 30,
hint_y - 10,
hint.get_width() + 60,
hint.get_height() + 20,
)
pygame.draw.rect(surface, config.COLOR_DIM, band, border_radius=10)
surface.blit(hint, (band.x + 30, hint_y))