diff --git a/A8/pong-oo_aufgabe.py b/A8/pong-oo_aufgabe.py index 83b4510..ce37c59 100755 --- a/A8/pong-oo_aufgabe.py +++ b/A8/pong-oo_aufgabe.py @@ -76,7 +76,7 @@ class BouncingBall(GameObject): self.size = [window.width, window.height] - self.object_image = pygame.image.load('ohm.png') + self.object_image = pygame.image.load('A8/ohm.png') self.object_size = (50, 50) self.object_position = [window.width / 2 - self.object_size[0] / 2, window.height /2 - self.object_size[1]] # self.object_speed = [randint(1,7), randint(1,7)] @@ -116,6 +116,7 @@ class BouncingBall(GameObject): if self.rect.colliderect(paddle.rect): self.object_speed[1] *= -1 + game_objects[OBJ_SCORE].increment() def draw(self, window): @@ -154,19 +155,24 @@ class Paddle(GameObject): ############################################################################### class Score(GameObject): - + def __init__(self, window): self.window = window self.score = 0 + self.font = pygame.font.Font(None, 36) - def increment(self, game_objects): - - self.score += 100 + def increment(self): + self.score += 10 def draw(self, window): - pass + text = self.font.render( + f"Score: {self.score}", + True, + (255, 255, 255) + ) + window.screen.blit(text, (10, 10)) def main(): """ @@ -194,6 +200,7 @@ def init(window : Window, game_objects): game_objects[OBJ_OVER] = GameOverLabel(window) game_objects[OBJ_BALL] = BouncingBall(window) game_objects[OBJ_PADDLE] = Paddle(window) + game_objects[OBJ_SCORE] = Score(window) def user_input(window, game_objects): diff --git a/A9/arbeitsblatt9.pdf b/A9/arbeitsblatt9.pdf new file mode 100644 index 0000000..956821c Binary files /dev/null and b/A9/arbeitsblatt9.pdf differ diff --git a/A9/highscores.txt b/A9/highscores.txt new file mode 100644 index 0000000..b853003 --- /dev/null +++ b/A9/highscores.txt @@ -0,0 +1,6 @@ +30#2020-06-11 18:34:26# +20#2020-06-11 19:08:10# +10#2020-06-11 19:08:21# +0#2020-06-11 19:11:14# +70#2020-06-11 19:08:56# +50#2020-06-11 19:09:25# diff --git a/A9/ohm.png b/A9/ohm.png new file mode 100644 index 0000000..bd4d275 Binary files /dev/null and b/A9/ohm.png differ diff --git a/A9/pong-oo-highscore-aufgabe.py b/A9/pong-oo-highscore-aufgabe.py new file mode 100644 index 0000000..2eb7ee2 --- /dev/null +++ b/A9/pong-oo-highscore-aufgabe.py @@ -0,0 +1,292 @@ +import pygame +from random import randint +from datetime import datetime + + +OBJ_OVER = "GameOver" +OBJ_BALL = "Ball" +OBJ_PADDLE = "Paddle" +OBJ_COUNTER = "Counter" +OBJ_HIGHSCORE = "Highscore" + +############################################################################### + +class GameObject(): + """ + Oberklasse für alle Objekte im Spiel + Jedes Objekt sollte sich selbst aktualisieren und darstellen können + """ + def update(self, game_objects): + pass + + def draw(self, window): + pass + + def signal_is_over(self, game_objects): + pass + +############################################################################### + +class Window(GameObject): + """ + Das eigentliche Fenster für das Spiel + Stellt den schwarzen Hintergrund dar und wird daher als erstes gezeichnet + Steuert auch die Spielgeschwindigkeit + """ + def __init__(self): + self.width = 640 + self.height = 480 + self.title = "Pong" + + pygame.init() + pygame.display.set_caption(self.title) + self.size = (self.width, self.height) + self.screen = pygame.display.set_mode(self.size) + self.clock = pygame.time.Clock() + + def update(self, game_objects): + self.clock.tick(50) + + def draw(self, window=None): + black = (0, 0, 0) + self.screen.fill(black) + +############################################################################### + +class GameOverLabel(GameObject): + """ + Boolsches "Objekt", das festhält, ob das Spiel verloren wurde + Stellt in diesem Fall die Game Over Schrift bereit + """ + def __init__(self, window): + font = pygame.font.Font(None, 36) + self.image = font.render('Game Over', 1, (255, 255, 255)) + self.rect = self.image.get_rect(centerx=window.width // 2, + centery=window.height // 2) + self.is_over = False + + def signal_is_over(self, game_objects): + self.is_over = True + + def draw(self, window): + if self.is_over: + window.screen.blit(self.image, self.rect) + +############################################################################### + +class Counter(GameObject): + """ + Zähler + """ + def __init__(self, window): + self.window = window + self.counter = 0 + + def increment(self): + self.counter += 10 + + def draw(self, window): + font = pygame.font.Font(None, 36) + self.image = font.render(f'{self.counter}', 1, (255, 255, 255)) + self.rect = self.image.get_rect(right=window.width-10 , top=10) + window.screen.blit(self.image, self.rect) + + +############################################################################### + +class Highscore(GameObject): + """ + Verwaltung der Highscore-Liste + """ + def __init__(self, window): + self.window = window + self.visible = False + self.font = pygame.font.Font(None, 24) + self.scores = {} + self.last_score = None + + ### TODO: Hier müssen die Highscores eingelesen werden + + + def signal_is_over(self, game_objects): + self.last_score = game_objects[OBJ_COUNTER].counter + self.scores[self.last_score] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + ### TODO: Hier müssen die Highscores gesichert werden + + self.visible = True + + def draw(self, window): + if self.visible: + sorted_scores = sorted(self.scores.keys()) + sorted_scores.reverse() + line_no = 1 + for index, key in enumerate(sorted_scores): + if index < 4 or key == self.last_score: + color = (255, 0, 0) if key == self.last_score else (255, 255, 255) + image = self.font.render(f'{key} Punkte am {self.scores[key]}', 1, color) + rect = image.get_rect(centerx=window.width // 2, top=window.height // 2 + line_no * 30) + line_no += 1 + window.screen.blit(image, rect) + + +############################################################################### + +class BouncingBall(GameObject): + """ + Das wandernde Ohm-Zeichen + Abprallen wird im Rahmen der Aktualisierung berechnet + Darstellung nur, wenn nicht gerade "Game Over angezeigt wird" + """ + def __init__(self, window): + self.window = window + self.image = pygame.image.load('ohm.png') + self.rect = self.image.get_rect() + self.rect.left = window.width // 2 - self.rect.width // 2 + self.rect.top = window.height // 2 - self.rect.height // 2 + maxspeed = 10 + self.dx = randint(2, maxspeed) + self.dy = randint(2, maxspeed) + + def update(self, game_objects): + self.is_visible = not game_objects[OBJ_OVER].is_over + if self.is_visible: + self.rect.left += self.dx + self.rect.top += self.dy + self.bounce(game_objects) + + def bounce(self, game_objects): + if self.rect.left < 0 or self.rect.right > self.window.width: + self.dx *= -1 + has_hit = self.hit(game_objects[OBJ_PADDLE]) + if has_hit: + game_objects[OBJ_COUNTER].increment() + if self.rect.top < 0 or has_hit: + self.dy *= -1 + if self.rect.bottom > self.window.height: + if not game_objects[OBJ_OVER].is_over: + for obj in game_objects.values(): + obj.signal_is_over(game_objects) + + def hit(self, paddle): + if self.dy < 0: + return False + return paddle.rect.colliderect(self.rect) + + def draw(self, window): + if self.is_visible: + window.screen.blit(self.image, self.rect) + +############################################################################### + +class Paddle(GameObject): + """ + Der Schläger + Darstellung nur, wenn nicht gerade "Game Over angezeigt wird" + """ + def __init__(self, window): + self.width = 100 + self.height = 10 + x = window.width // 2 - self.width // 2 + y = window.height - 2 * self.height + self.rect = pygame.Rect(x, y, self.width, self.height) + self.color = (255, 0, 0), # rot + self.speed = 10 + self.dx = 0 + self.dy = 0 + + def update(self, game_objects): + self.is_visible = not game_objects[OBJ_OVER].is_over + if self.is_visible: + self.rect.left += self.dx + self.rect.top += self.dy + + def draw(self, window): + if self.is_visible: + pygame.draw.rect(window.screen, self.color, self.rect) + +############################################################################### + +def main(): + """ + Main-Funktion mit Game-Loop + Hostet die beiden zentralen Variablen "window" und "game_objects" + """ + window = Window() + game_objects = dict() + init(window, game_objects) + + running = True + + while running: + running = user_input(window, game_objects) + update(window, game_objects) + draw(window, game_objects) + + +def init(window, game_objects): + """ + Anlegen aller Objekte des Spiels + """ + game_objects[OBJ_OVER] = GameOverLabel(window) + game_objects[OBJ_BALL] = BouncingBall(window) + game_objects[OBJ_PADDLE] = Paddle(window) + game_objects[OBJ_COUNTER] = Counter(window) + game_objects[OBJ_HIGHSCORE] = Highscore(window) + + +def user_input(window, game_objects): + """ + Abarbeiten aller Events + :return: False, falls das Spiel beendet wird, sonst Truepong-oo.py + """ + + def process_event(): + """ + Verarbeitung eines Events + """ + if event.type == pygame.QUIT: + return False + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE: + return False + if event.key == pygame.K_SPACE and game_objects[OBJ_OVER].is_over: + init(window, game_objects) + if event.key == pygame.K_LEFT: + game_objects[OBJ_PADDLE].dx -= game_objects[OBJ_PADDLE].speed + if event.key == pygame.K_RIGHT: + game_objects[OBJ_PADDLE].dx += game_objects[OBJ_PADDLE].speed + if event.type == pygame.KEYUP: + if event.key == pygame.K_LEFT: + game_objects[OBJ_PADDLE].dx += game_objects[OBJ_PADDLE].speed + if event.key == pygame.K_RIGHT: + game_objects[OBJ_PADDLE].dx -= game_objects[OBJ_PADDLE].speed + return True + + result = True + for event in pygame.event.get(): + result = result and process_event() + return result + + +def update(window, game_objects): + """ + Aktualisierung aller Objekt + """ + window.update(game_objects) + for o in game_objects.values(): + o.update(game_objects) + + +def draw(window, game_objects): + """ + Zeichnen aller Objekte + """ + window.draw() + for o in game_objects.values(): + o.draw(window) + pygame.display.flip() + + +if __name__ == "__main__": + main()