diff --git a/apollo.py b/apollo.py index fd49437..353374b 100644 --- a/apollo.py +++ b/apollo.py @@ -1,42 +1,86 @@ import pygame + +# Diese Funktionen führen die Matrixrechnung für die Drehung aus. from compute import matmul, rot_2D, transpose + +# Apollo erbt von Moon. Dadurch bewegt sich auch der Mond um die Erde. from moon import Moon -# Colors -WHITE = (255, 255, 255) + RED = (255, 0, 0) +APOLLO_RADIUS = 5 +APOLLO_ORBIT_RADIUS = 30.0 + class Apollo(Moon): - """Die Raumkapsel Apollo kreist um den Mond""" + """Die rote Raumkapsel Apollo kreist um den Mond.""" - def __init__(self, title: str = "Apollo", fps: int = 60, size: tuple[int, int] = (640, 400)): + def __init__( + self, + title: str = "Apollo", + fps: int = 60, + size: tuple[int, int] = (640, 400), + ) -> None: + """Bereitet die Mond- und Apollo-Animation vor.""" + + # Erst werden Erde und Mond eingerichtet. super().__init__(title, fps, size) - # Apollo orbit radius around the moon (relative to moon position) - self.apollo_radius = 30.0 - # Initial position relative to moon - self.apollo_offset = (0.0, self.apollo_radius) - # Apollo angular speed: double moon speed, opposite direction - self.theta = -2 * self.rot_moon[0][0] # since rot_2D(theta) second element is cos=rot[0][0] - self.rot_apollo = rot_2D(self.theta) + + # Apollo startet 30 Pixel unterhalb des Mondes. + # Das ist die Position relativ zum Mond. + self.position_apollo = (0.0, APOLLO_ORBIT_RADIUS) + + # Apollo dreht sich doppelt so schnell wie der Mond, + # aber in die entgegengesetzte Richtung. + self.theta_apollo = -2 * self.theta + + # Aus dem Winkel wird eine Drehmatrix erstellt. + self.rot_apollo = rot_2D(self.theta_apollo) def update_game(self) -> bool: - # First let the moon move + """Bewegt den Mond und Apollo um jeweils einen Schritt.""" + + # Die Moon-Methode bewegt zuerst den Mond um die Erde. super().update_game() - # Rotate Apollo around the moon - point = transpose([list(self.apollo_offset)]) + + # Eine Position als Spalte für die Matrixrechnung vorbereiten. + # Aus (x, y) wird [[x], [y]]. + point = transpose([list(self.position_apollo)]) + + # Die Drehmatrix dreht Apollo ein kleines Stück weiter. result = matmul(self.rot_apollo, point) - self.apollo_offset = (result[0][0], result[1][0]) + + # Das Matrix-Ergebnis wieder als (x, y) speichern. + self.position_apollo = (result[0][0], result[1][0]) + + # True sagt dem Spiel, dass die Animation weiterlaufen soll. return True - def draw_game(self) -> None: - # Draw background and Earth and Moon via super() - super().draw_game() - # Compute Apollo absolute position - moon_abs = (self.center[0] + self.position_moon[0], self.center[1] + self.position_moon[1]) - apollo_pos = (int(moon_abs[0] + self.apollo_offset[0]), int(moon_abs[1] + self.apollo_offset[1])) + def draw_content(self) -> None: + """Zeichnet Erde, Mond und Apollo auf den Bildschirm.""" + + # Die Moon-Methode zeichnet zuerst den Hintergrund, die Erde und den Mond. + super().draw_content() + + # Die Bildschirmposition des Mondes: + # Fenstermitte plus Mondposition relativ zur Erde. + moon_x = self.center[0] + self.position_moon[0] + moon_y = self.center[1] + self.position_moon[1] + + # Apollo-Position = Mondposition plus Apollo-Abstand zum Mond. + apollo_x = int(moon_x + self.position_apollo[0]) + apollo_y = int(moon_y + self.position_apollo[1]) + + # Den Bildschirm holen und Apollo als roten Kreis zeichnen. screen = pygame.display.get_surface() - pygame.draw.circle(screen, RED, apollo_pos, 5) - pygame.display.flip() + if screen is not None: + pygame.draw.circle( + screen, + RED, + (apollo_x, apollo_y), + APOLLO_RADIUS, + ) + if __name__ == "__main__": - Apollo().run() + Apollo().run() \ No newline at end of file diff --git a/compute.py b/compute.py index be2f526..b19644e 100644 --- a/compute.py +++ b/compute.py @@ -1,7 +1,3 @@ -"""Einfache Matrixoperationen: -Multiplikation, Transponieren und Drehung um 90° im Uhrzeigersinn. -""" - from __future__ import annotations from typing import List diff --git a/moon.py b/moon.py index ae34f9c..d327b79 100644 --- a/moon.py +++ b/moon.py @@ -32,6 +32,10 @@ class Moon(Game): # Moon ist ein Spiel und übernimmt Funktionen von Game return True # Sagt dem Spiel: Es soll weiterlaufen def draw_game(self) -> None: + self.draw_content() + pygame.display.flip() # Zeigt das fertige Bild im Fenster an + + def draw_content(self): """Zeichnet Erde und Mond.""" screen = pygame.display.get_surface() # Holt die Zeichenfläche des Fensters screen.fill(BLACK) # Löscht das alte Bild und färbt den Hintergrund schwarz @@ -41,8 +45,7 @@ class Moon(Game): # Moon ist ein Spiel und übernimmt Funktionen von Game int(self.center[1] + self.position_moon[1]), # Mittelpunkt-y plus Mond-y ) pygame.draw.circle(screen, WHITE, moon_pos, MOON_RADIUS) # Zeichnet den Mond - pygame.display.flip() # Zeigt das fertige Bild im Fenster an -if __name__ == "__main__": # Prüft, ob diese Datei direkt gestartet wurde - Moon().run() # Erstellt das Spiel und startet die Spielschleife \ No newline at end of file +if __name__ == "__main__": + Moon().run() \ No newline at end of file