aboutsummaryrefslogtreecommitdiff
path: root/src/splitscreen_duo/games/game_base.py
diff options
context:
space:
mode:
authorZoltan Szabatin <[email protected]>2025-03-02 19:01:12 -0800
committerZoltan Szabatin <[email protected]>2025-03-02 19:01:12 -0800
commit3ba60ffec522cd35c137573f666aaea3ee899c7c (patch)
treec7e44a62f4dd701669aee1f318ed17aff28ae858 /src/splitscreen_duo/games/game_base.py
parentfeat: Add breakout game (diff)
downloadsplitscreen-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.py140
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