commit bf74311adda1d289e06ede129a9a0db348830e33 Author: Brockmann Date: Sat Oct 25 15:25:29 2025 +0200 Assignment 1 commit: Moon & Apollo diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Prog3A-Moon.iml b/.idea/Prog3A-Moon.iml new file mode 100644 index 0000000..99499be --- /dev/null +++ b/.idea/Prog3A-Moon.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..2fcaf80 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..26e69cb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/game/Moon.py b/game/Moon.py new file mode 100644 index 0000000..de737f2 --- /dev/null +++ b/game/Moon.py @@ -0,0 +1,29 @@ +import pygame + +from game.game import Game +from numeric.compute import rot_2D, matmul + + +class Moon(Game): + def __init__(self): + super().__init__("Moon") + self.moon_position = None + self.center = (540, 355) + self.moon_distance = [[200], [0]] + self.angle = 0 + + def update_game(self): + self.angle = pygame.time.get_ticks() / 1000 # Zeit = Winkel + rot = rot_2D(self.angle) + rotated = matmul(rot, self.moon_distance) + self.moon_position = ( + int(self.center[0] + rotated[0][0]), + int(self.center[1] + rotated[1][0]) + ) + return True + + def draw_game(self): + self.screen.fill((30,30,30)) + pygame.draw.circle(self.screen, (0,0,255), self.center, 12) + pygame.draw.circle(self.screen, (255,255,255), self.moon_position, 8) + pygame.display.flip() \ No newline at end of file diff --git a/game/__init__.py b/game/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/game/apollo.py b/game/apollo.py new file mode 100644 index 0000000..c7e7402 --- /dev/null +++ b/game/apollo.py @@ -0,0 +1,26 @@ +import pygame + +from game.Moon import Moon +from numeric.compute import rot_2D, matmul + + +class Apollo(Moon): + def __init__(self): + super().__init__() + self.orbiter_position = None + self.orbiter_distance = [[50], [0]] + + def update_game(self): + super().update_game() + rot = rot_2D(-self.angle) + rotated = matmul(rot, self.orbiter_distance) + self.orbiter_position = ( + int(self.moon_position[0] + rotated[0][0]), + int(self.moon_position[1] + rotated[1][0]) + ) + return True + + def draw_game(self): + super().draw_game() + pygame.draw.circle(self.screen, (255,0,0), self.orbiter_position, 4) + pygame.display.flip() \ No newline at end of file diff --git a/game/game.py b/game/game.py new file mode 100644 index 0000000..53909c3 --- /dev/null +++ b/game/game.py @@ -0,0 +1,53 @@ +import pygame + +class Game: + + def __init__(self, title, fps=60, size=(1080, 720)): + self.title = title + self.fps = fps + self.size = size + self.clock = pygame.time.Clock() + self.dt = 0 + self.screen = None + + def init_game(self): + pygame.init() + pygame.display.set_caption(self.title) + self.screen = pygame.display.set_mode(self.size) + + + def game_loop(self): + while True: + # Berechnung der Zeitdifferenz seit dem letzten Frame + self.dt = self.clock.tick(self.fps) / 1000 + if self.event_handling() == False: + break + if self.update_game() == False: + break + self.draw_game() + + def exit_game(self): + pygame.quit() + + def event_handling(self): # bleibt in der Unterklasse unverändert + for event in pygame.event.get(): + if not self.handle_event(event): + return False + return True + + def handle_event(self, event): # wird in der Unterklasse überschrieben + if event.type == pygame.QUIT: + return False + return True + + def update_game(self): + return True + + def draw_game(self): + pygame.display.flip() + + def run(self): + self.init_game() + self.game_loop() + self.exit_game() + diff --git a/main.py b/main.py new file mode 100644 index 0000000..982af5e --- /dev/null +++ b/main.py @@ -0,0 +1,7 @@ +from game.Moon import Moon +from game.apollo import Apollo +from game.game import Game + +if __name__ == '__main__': + game = Apollo() + game.run() diff --git a/numeric/__init__.py b/numeric/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/numeric/compute.py b/numeric/compute.py new file mode 100644 index 0000000..fbefdf5 --- /dev/null +++ b/numeric/compute.py @@ -0,0 +1,76 @@ +from typing import List +import math + + +def product(factors: List[int]) -> int: + """ + :param factors: A list of factors + :return: The product + """ + if not isinstance(factors, List) or not isinstance(factors[0], int): + raise ValueError("List of integers required") + + result = 1 + + for i in factors: + result *= factors[i] + + return result + + +def matmul(a: List[List[float]], b: List[List[float]]) -> List[List[float]]: + """ + Matrix multiplication + :param a: the first matrix + :param b: the second matrix + :return: + """ + if len(a[0]) != len(b): + raise ValueError("Breath of first matrix must be equivalent to the height of the second") + + result = [] + for i in range(len(a)): + result.append([0] * len(b[0])) + + for i in range(len(a)): + for j in range(len(b[0])): + for k in range(len(b)): + result[i][j] += a[i][k] * b[k][j] + + return result + + +def transpose(matrix: List[List[int]]) -> list[list[int]]: + """ + Transposes any given matrix + :param matrix: A nested list of integers describing a matrix + :return: transposed matrix + :throws: Value error if the parameter is not of the given type + """ + + if not isinstance(matrix, List) or not isinstance(matrix[0], List) or not isinstance(matrix[0][0], int): + raise ValueError("Argument needs to be a nested list of integers") + + result = [] + + for i in range(len(matrix[0])): + result.append([0] * len(matrix)) + + for y in range(len(matrix)): + for x in range(len(matrix[0])): + result[x][y] = matrix[y][x] + + return result + + +def rot_2D(angle) -> list[list[float]]: + """ + Creates a rotation matrix from any given angle + :param angle: The angle (degrees) + :return: The rotation matrix + :throws: Value error if the parsed angle is not of a numeric type + """ + if not isinstance(angle, float) and not isinstance(angle, int): + raise ValueError("The parameter angle must be an instance of a numeric datatype") + + return [[math.cos(angle), -math.sin(angle)], [math.sin(angle), math.cos(angle)]] diff --git a/util/__init__.py b/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/util/tools.py b/util/tools.py new file mode 100644 index 0000000..4e67e39 --- /dev/null +++ b/util/tools.py @@ -0,0 +1,21 @@ +def substring(string: str, start: int, end: int = 0) -> str: + """ + A substring function + :param string: The string + :param start: The starting index + :param end: The ending index. If None, this is set to the length of the substring :return: + """ + if not isinstance(string, str): + raise ValueError("No string provided") + if not isinstance(start, int): + raise ValueError("No starting index provided") + + if end is None: + end = len(str) + + result = "" + + for i in range(start, end): + result += string[i] + + return result