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:
1 parent
6a2c891c3e
commit
de550e1d4d
24 files changed
+2269
-1008
No files matched your search
@@ -0,0 +1,108 @@
|
||||
"""Tastatur und Controller → abstrakte Aktionen.
|
||||
|
||||
Die Aktionen sind absichtlich generisch gehalten. Die spätere Namenseingabe
|
||||
per Controller benutzt dieselben Richtungen (Buchstabe weiter/zurück,
|
||||
Position wechseln), deshalb gibt es hier keine spielspezifischen Namen.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
|
||||
import pygame
|
||||
|
||||
from . import config
|
||||
|
||||
|
||||
class Action(enum.Enum):
|
||||
"""Abstrakte Eingabe – unabhängig davon, ob Tastatur oder Controller."""
|
||||
|
||||
PRIMARY = "primary" # Space / Enter / Controller A
|
||||
LEFT = "left" # Pfeil links / D-Pad links
|
||||
RIGHT = "right" # Pfeil rechts / D-Pad rechts
|
||||
UP = "up" # Pfeil hoch / D-Pad hoch
|
||||
DOWN = "down" # Pfeil runter / D-Pad runter
|
||||
BACK = "back" # Esc / Controller B
|
||||
|
||||
|
||||
#: Tastaturbelegung
|
||||
KEY_ACTIONS: dict[int, Action] = {
|
||||
pygame.K_SPACE: Action.PRIMARY,
|
||||
pygame.K_RETURN: Action.PRIMARY,
|
||||
pygame.K_KP_ENTER: Action.PRIMARY,
|
||||
pygame.K_LEFT: Action.LEFT,
|
||||
pygame.K_RIGHT: Action.RIGHT,
|
||||
pygame.K_UP: Action.UP,
|
||||
pygame.K_DOWN: Action.DOWN,
|
||||
pygame.K_ESCAPE: Action.BACK,
|
||||
}
|
||||
|
||||
#: Controller-Tasten (Xbox-Layout: 0=A, 1=B, 2=X, 3=Y)
|
||||
BUTTON_ACTIONS: dict[int, Action] = {
|
||||
0: Action.PRIMARY,
|
||||
1: Action.BACK,
|
||||
2: Action.LEFT,
|
||||
3: Action.UP,
|
||||
}
|
||||
|
||||
#: D-Pad, das als Hat gemeldet wird
|
||||
HAT_ACTIONS: dict[tuple[int, int], Action] = {
|
||||
(-1, 0): Action.LEFT,
|
||||
(1, 0): Action.RIGHT,
|
||||
(0, -1): Action.UP,
|
||||
(0, 1): Action.DOWN,
|
||||
}
|
||||
|
||||
#: Analogstick: ab diesem Ausschlag gilt eine Richtung als gewollt
|
||||
AXIS_DEADZONE = 0.6
|
||||
|
||||
|
||||
def actions_from_event(event: pygame.event.Event) -> list[Action]:
|
||||
"""Übersetzt ein pygame-Event in null bis eine Aktion."""
|
||||
if event.type == pygame.KEYDOWN:
|
||||
action = KEY_ACTIONS.get(event.key)
|
||||
return [action] if action else []
|
||||
|
||||
if event.type == pygame.JOYBUTTONDOWN:
|
||||
action = BUTTON_ACTIONS.get(event.button)
|
||||
return [action] if action else []
|
||||
|
||||
if event.type == pygame.JOYHATMOTION:
|
||||
action = HAT_ACTIONS.get(tuple(event.value))
|
||||
return [action] if action else []
|
||||
|
||||
if event.type == pygame.JOYAXISMOTION:
|
||||
if event.axis == 0 and abs(event.value) >= AXIS_DEADZONE:
|
||||
return [Action.RIGHT if event.value > 0 else Action.LEFT]
|
||||
if event.axis == 1 and abs(event.value) >= AXIS_DEADZONE:
|
||||
return [Action.DOWN if event.value > 0 else Action.UP]
|
||||
return []
|
||||
|
||||
|
||||
def connected_controllers() -> list[str]:
|
||||
"""Namen aller angeschlossenen Controller (leer, wenn keiner da ist)."""
|
||||
names = []
|
||||
for index in range(pygame.joystick.get_count()):
|
||||
try:
|
||||
stick = pygame.joystick.Joystick(index)
|
||||
stick.init()
|
||||
names.append(stick.get_name())
|
||||
except pygame.error:
|
||||
continue
|
||||
return names
|
||||
|
||||
|
||||
def describe_controller_setup() -> str:
|
||||
names = connected_controllers()
|
||||
if not names:
|
||||
return "Controller: keiner erkannt (Tastatur: Space=Snap, ←=Drehen, ↑=OnTop, Esc=Ende)"
|
||||
return "Controller: " + ", ".join(names)
|
||||
|
||||
|
||||
def controller_hint_lines() -> list[str]:
|
||||
"""Kurzhilfe fürs Log beim Start."""
|
||||
return [
|
||||
describe_controller_setup(),
|
||||
f"Zielauflösung {config.SCREEN_WIDTH}x{config.SCREEN_HEIGHT}, "
|
||||
f"{config.FPS} fps",
|
||||
]
|
||||
Reference in new issue
Block a user