Files

90 lines
2.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Der Koffer: Geometrie und Einlaufbewegung.
Bewusst ohne ``pygame``-Abhängigkeit, damit die Regeln testbar bleiben.
"""
from __future__ import annotations
from dataclasses import dataclass
from . import config
from .difficulty import DEFAULT_DIFFICULTY, Difficulty
@dataclass
class Case:
"""Ein Koffer im Auflieger.
``units_w`` / ``units_h`` beschreiben die **aktuelle** Grundfläche in
Kasten-Einheiten. Eine Drehung tauscht die beiden Werte.
``texture`` merkt sich die Orientierung, in der der Koffer eingelaufen ist.
Die Grafik bleibt dadurch immer dieselbe – ein gedrehter Koffer wird nur um
90° gedreht gezeichnet und bekommt keine andere Textur.
"""
units_w: int
units_h: int
x: float
y: float
color: tuple[int, int, int] = config.CASE_COLORS[0]
texture: tuple[int, int] | None = None
placed: bool = False
snapped: bool = False
allow_snap: bool = False
can_rotate: bool = True
def __post_init__(self) -> None:
if self.texture is None:
self.texture = (self.units_w, self.units_h)
# -- Geometrie ------------------------------------------------------
@property
def width(self) -> float:
return self.units_w * config.UNIT_LENGTH
@property
def height(self) -> float:
return self.units_h * config.UNIT_HEIGHT
@property
def right(self) -> float:
return self.x + self.width
@property
def bottom(self) -> float:
return self.y + self.height
@property
def is_rotated(self) -> bool:
"""Steht der Koffer quer zu seiner Textur?"""
return (self.units_w, self.units_h) != self.texture
# -- Bewegung -------------------------------------------------------
def move(
self,
dt: float,
wall_x: float,
difficulty: Difficulty = DEFAULT_DIFFICULTY,
) -> None:
"""Bewegt den Koffer nach links, mit Abbremsen kurz vor der Barriere."""
if self.placed:
return
distance = self.x - wall_x
speed = (
difficulty.speed_fast
if distance > config.FAST_TO_SLOW_DISTANCE
else difficulty.speed_slow
)
self.x -= speed * dt
if self.x <= wall_x + config.SNAP_WINDOW:
self.allow_snap = True
def rotate_footprint(self) -> None:
"""Tauscht Breite und Höhe (nach einer 90°-Drehung)."""
self.units_w, self.units_h = self.units_h, self.units_w
def fits_trailer_height(self) -> bool:
"""Passt der Koffer nach einer Drehung noch in die Höhe des Aufliegers?"""
return self.width <= config.TRAILER_HEIGHT