diff options
| author | Zoltan Szabatin <[email protected]> | 2025-03-02 19:01:12 -0800 |
|---|---|---|
| committer | Zoltan Szabatin <[email protected]> | 2025-03-02 19:01:12 -0800 |
| commit | 3ba60ffec522cd35c137573f666aaea3ee899c7c (patch) | |
| tree | c7e44a62f4dd701669aee1f318ed17aff28ae858 /src/splitscreen_duo/games/game_base.py | |
| parent | feat: Add breakout game (diff) | |
| download | splitscreen-duo-3ba60ffec522cd35c137573f666aaea3ee899c7c.tar.xz splitscreen-duo-3ba60ffec522cd35c137573f666aaea3ee899c7c.zip | |
refactor: Create base game class for games
Diffstat (limited to 'src/splitscreen_duo/games/game_base.py')
| -rw-r--r-- | src/splitscreen_duo/games/game_base.py | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/splitscreen_duo/games/game_base.py b/src/splitscreen_duo/games/game_base.py new file mode 100644 index 0000000..ff45686 --- /dev/null +++ b/src/splitscreen_duo/games/game_base.py @@ -0,0 +1,140 @@ +import pygame +import json +from ..command import Command +import logging + +logger = logging.getLogger(__name__) + + +class GameBase: + def __init__(self, screen, serial, instance): + self.screen = screen + self.serial = serial + self.instance = instance + self.font = pygame.font.Font(None, 36) + self.is_running = True + self.opponent_dead = False + self.my_score = 0 + self.opponent_score = 0 + self.waiting = False + self.score_display_time = 0 + self.BLACK = (0, 0, 0) + self.WHITE = (255, 255, 255) + + def handle_common_events(self, event): + if event.type == pygame.QUIT: + return {"command": Command.QUIT.value, "action": None, "value": None} + elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: + return None + + return None + + def check_serial(self): + if self.serial.in_waiting() > 0: + data = self.serial.readline().decode("utf-8").strip() + + logger.debug(f"received serial data during check_serial: {data}") + + message = json.loads(data) + + if message.get("command") == Command.SCORE.value: + self.opponent_dead = True + self.opponent_score = message.get("value", 0) + + return True + elif message.get("command") == Command.QUIT.value: + return {"command": Command.QUIT.value, "action": None, "value": None} + return False + + def end_game(self, score): + self.my_score = score + + logger.debug(f"ending game, sending score: {self.my_score}") + + self.serial.write( + json.dumps( + {"command": Command.SCORE.value, "action": None, "value": self.my_score} + ).encode("utf-8") + ) + + if self.opponent_dead: + self.score_display_time = pygame.time.get_ticks() + + logger.debug("opponent already dead, starting score display") + else: + self.waiting = True + + logger.debug("waiting for opponent to finish") + + def update(self): + if self.waiting: + self.screen.fill(self.BLACK) + + text = self.font.render("waiting for opponent ...", True, self.WHITE) + + self.screen.blit( + text, + ( + self.screen.get_width() // 2 - text.get_width() // 2, + self.screen.get_height() // 2, + ), + ) + pygame.display.flip() + + if self.serial.in_waiting() > 0: + data = self.serial.readline().decode("utf-8").strip() + + logger.debug(f"received serial data while waiting: {data}") + + message = json.loads(data) + + if message.get("command") == Command.SCORE.value: + self.opponent_score = message.get("value", 0) + self.waiting = False + self.score_display_time = pygame.time.get_ticks() + + logger.debug("received opponent's score, starting score display") + elif message.get("command") == Command.QUIT.value: + logger.info("received quit command while waiting") + + return { + "command": Command.QUIT.value, + "action": None, + "value": None, + } + + elif self.score_display_time: + self.screen.fill(self.BLACK) + + my_text = self.font.render(f"Your Score: {self.my_score}", True, self.WHITE) + opp_text = self.font.render( + f"Your Opponent's Score: {self.opponent_score}", True, self.WHITE + ) + + self.screen.blit( + my_text, + ( + self.screen.get_width() // 2 - my_text.get_width() // 2, + self.screen.get_height() // 2 - 20, + ), + ) + self.screen.blit( + opp_text, + ( + self.screen.get_width() // 2 - opp_text.get_width() // 2, + self.screen.get_height() // 2 + 20, + ), + ) + pygame.display.flip() + + if pygame.time.get_ticks() - self.score_display_time > 3000: + logger.debug("score display timeout reached, exiting game") + + self.is_running = False + + return None + + return None + + def main_loop(self): + raise NotImplementedError |