"""Zeichenhelfer für Körperformen – gemeinsam genutzt von Renderer und Vorschau-Kachel.""" from __future__ import annotations import math from typing import TypeAlias import pygame #: RGB- oder RGBA-Farbe (RGBA für halbtransparente Vorschauen). DrawColor: TypeAlias = tuple[int, ...] def draw_circle( surface: pygame.Surface, color: DrawColor, outline: DrawColor, center: tuple[float, float], radius: float, *, outline_width: int, angle: float | None = None, marker_length: float = 0.0, ) -> None: """Zeichnet einen geglätteten Kreis mit Umrandung und optionalem Drehmarker. Args: surface: Zielfläche. color: Füllfarbe. outline: Farbe von Umrandung und Drehmarker. center: Mittelpunkt in Bildschirmkoordinaten. radius: Radius in px. outline_width: Linienstärke der Umrandung. angle: Drehwinkel in rad. Ohne Marker wäre die Drehung eines einfarbigen Kreises unsichtbar – man sähe nicht, ob er rollt oder rutscht. marker_length: Länge des Markers als Anteil des Radius. """ # Die Füllung braucht keine Kantenglättung: Die geglättete Umrandung liegt genau auf # ihrem Rand und verdeckt die Treppenstufen. Das halbiert die teuren aacircle-Aufrufe. pygame.draw.circle(surface, color, center, radius) pygame.draw.aacircle(surface, outline, center, radius, outline_width) if angle is not None: end = ( center[0] + math.cos(angle) * radius * marker_length, center[1] + math.sin(angle) * radius * marker_length, ) pygame.draw.line(surface, outline, center, end, outline_width) def draw_box( surface: pygame.Surface, color: DrawColor, outline: DrawColor, center: tuple[float, float], half_extents: tuple[float, float], *, outline_width: int, corner_radius: int = 0, ) -> None: """Zeichnet ein achsenparalleles Rechteck mit Umrandung.""" half_width, half_height = half_extents rect = pygame.Rect(0, 0, round(2 * half_width), round(2 * half_height)) rect.center = (round(center[0]), round(center[1])) pygame.draw.rect(surface, color, rect, border_radius=corner_radius) pygame.draw.rect(surface, outline, rect, outline_width, border_radius=corner_radius)