diff options
Diffstat (limited to 'src/splitscreen_duo')
| -rw-r--r-- | src/splitscreen_duo/__init__.py | 5 | ||||
| -rw-r--r-- | src/splitscreen_duo/games/benchmark.py | 37 | ||||
| -rw-r--r-- | src/splitscreen_duo/games/breakout.py | 26 | ||||
| -rw-r--r-- | src/splitscreen_duo/games/game_base.py | 17 | ||||
| -rw-r--r-- | src/splitscreen_duo/games/pong.py | 43 | ||||
| -rw-r--r-- | src/splitscreen_duo/games/snake.py | 12 | ||||
| -rw-r--r-- | src/splitscreen_duo/menu.py | 45 |
7 files changed, 160 insertions, 25 deletions
diff --git a/src/splitscreen_duo/__init__.py b/src/splitscreen_duo/__init__.py index defba37..3df7290 100644 --- a/src/splitscreen_duo/__init__.py +++ b/src/splitscreen_duo/__init__.py @@ -28,6 +28,7 @@ def main() -> int: print("The Dual Screen Console") logger.info(f"running as {os.getenv('INSTANCE', 'unknown')}") menu.init_display() + menu.set_screen_orientation(is_joint_mode[0]) font = pygame.font.Font(None, 36) BLACK = (0, 0, 0) @@ -92,10 +93,12 @@ def main() -> int: if command == Command.ENTER_JOINT_MODE.value: is_joint_mode[0] = True + menu.set_screen_orientation(is_joint_mode[0]) logger.info("secondary entering joint mode") elif command == Command.EXIT_JOINT_MODE.value: is_joint_mode[0] = False + menu.set_screen_orientation(is_joint_mode[0]) logger.info("secondary exiting joint mode") elif command == Command.QUIT.value: pygame.quit() @@ -167,8 +170,6 @@ def main() -> int: if result == 0: return 0 - menu.draw_menu() - pygame.quit() return 0 diff --git a/src/splitscreen_duo/games/benchmark.py b/src/splitscreen_duo/games/benchmark.py index 3c8ea81..efe48c3 100644 --- a/src/splitscreen_duo/games/benchmark.py +++ b/src/splitscreen_duo/games/benchmark.py @@ -18,10 +18,18 @@ class Ball: def main_loop(screen, serial): clock = pygame.time.Clock() + screen_width = screen.get_width() + screen_height = screen.get_height() + + global BALL_SIZE + + BALL_SIZE = max(15, min(25, min(screen_width, screen_height) // 20)) + is_vertical = screen_height > screen_width * 1.5 ball_list = [] balls = 1 - ball = Ball(screen.get_width(), screen.get_height()) + ball = Ball(screen_width, screen_height) is_running = True + font = pygame.font.Font(None, 36) ball_list.append(ball) @@ -52,11 +60,38 @@ def main_loop(screen, serial): if ball.x > screen.get_width() - BALL_SIZE or ball.x < BALL_SIZE: ball.change_x *= -1 + current_width = screen.get_width() + current_height = screen.get_height() + + if current_width != screen_width or current_height != screen_height: + screen_width = current_width + screen_height = current_height + BALL_SIZE = max(15, min(25, min(screen_width, screen_height) // 20)) + is_vertical = screen_height > screen_width * 1.5 + + for b in ball_list: + if b.x > screen_width - BALL_SIZE: + b.x = screen_width - BALL_SIZE + + if b.y > screen_height - BALL_SIZE: + b.y = screen_height - BALL_SIZE + screen.fill(BLACK) for ball in ball_list: pygame.draw.circle(screen, WHITE, [int(ball.x), int(ball.y)], BALL_SIZE) + fps = clock.get_fps() + fps_text = font.render(f"FPS: {fps:.1f}", True, WHITE) + ball_text = font.render(f"Balls: {balls}", True, WHITE) + + if is_vertical: + screen.blit(fps_text, (screen_width // 2 - fps_text.get_width() // 2, 10)) + screen.blit(ball_text, (screen_width // 2 - ball_text.get_width() // 2, 40)) + else: + screen.blit(fps_text, (10, 10)) + screen.blit(ball_text, (10, 40)) + pygame.display.flip() # clock.tick(60) clock.tick() diff --git a/src/splitscreen_duo/games/breakout.py b/src/splitscreen_duo/games/breakout.py index 3f6aa16..6a5e2cc 100644 --- a/src/splitscreen_duo/games/breakout.py +++ b/src/splitscreen_duo/games/breakout.py @@ -23,12 +23,27 @@ logger = logging.getLogger(__name__) class Breakout(GameBase): def __init__(self, screen, serial, instance, is_joint_mode=False): super().__init__(screen, serial, instance, is_joint_mode) - self.screen_width = screen.get_width() - self.screen_height = screen.get_height() - self.reset() def reset(self): + global PADDLE_WIDTH, PADDLE_HEIGHT, BALL_SIZE, BRICK_WIDTH, BRICK_HEIGHT, BRICK_ROWS, BRICK_COLS, SPEED + + scale_factor = min(self.screen_width / 640, self.screen_height / 480) + + if self.is_vertical: + PADDLE_WIDTH = min(100, int(80 * scale_factor)) + BRICK_COLS = max(5, min(8, int(self.screen_width / 90))) + else: + PADDLE_WIDTH = min(100, int(100 * scale_factor)) + BRICK_COLS = max(6, min(10, int(self.screen_width / 90))) + + PADDLE_HEIGHT = max(8, int(10 * scale_factor)) + BALL_SIZE = max(6, int(10 * scale_factor)) + BRICK_WIDTH = int((self.screen_width - 20) / BRICK_COLS) - 5 + BRICK_HEIGHT = max(15, min(30, int(30 * scale_factor))) + BRICK_ROWS = max(3, min(5, int(self.screen_height / 120))) + SPEED = max(3, min(5, int(5 * scale_factor))) + self.paddle = [ self.screen_width // 2 - PADDLE_WIDTH // 2, self.screen_height - 40, @@ -163,7 +178,10 @@ class Breakout(GameBase): if not self.is_joint_mode or self.instance != "primary": score_text = self.font.render(f"Score: {self.score}", True, WHITE) - self.screen.blit(score_text, (10, 10)) + if self.is_vertical: + self.screen.blit(score_text, (self.screen_width // 2 - score_text.get_width() // 2, 10)) + else: + self.screen.blit(score_text, (10, 10)) pygame.display.flip() clock.tick(60) diff --git a/src/splitscreen_duo/games/game_base.py b/src/splitscreen_duo/games/game_base.py index 8ef02ec..a539ba0 100644 --- a/src/splitscreen_duo/games/game_base.py +++ b/src/splitscreen_duo/games/game_base.py @@ -24,6 +24,9 @@ class GameBase: self.BLACK = (0, 0, 0) self.WHITE = (255, 255, 255) self.input_handler = Input(debug=os.getenv("DEVELOPMENT", "").lower() != "") + self.screen_width = screen.get_width() + self.screen_height = screen.get_height() + self.is_vertical = is_joint_mode def handle_common_events(self, event): action = self.input_handler.get_input(event) @@ -93,7 +96,21 @@ class GameBase: + b"\n" ) + def update_screen_dimensions(self): + current_width = self.screen.get_width() + current_height = self.screen.get_height() + + if (current_width != self.screen_width or current_height != self.screen_height): + self.screen_width = current_width + self.screen_height = current_height + self.is_vertical = current_height > current_width * 1.5 + + self.reset() + logger.debug(f"screen dimensions updated: {self.screen_width}x{self.screen_height}, vertical: {self.is_vertical}") + def update(self): + self.update_screen_dimensions() + if self.is_joint_mode: return None diff --git a/src/splitscreen_duo/games/pong.py b/src/splitscreen_duo/games/pong.py index 0c0df84..d82cdc7 100644 --- a/src/splitscreen_duo/games/pong.py +++ b/src/splitscreen_duo/games/pong.py @@ -19,8 +19,7 @@ logger = logging.getLogger(__name__) class Pong(GameBase): def __init__(self, screen, serial, instance, is_joint_mode=False): super().__init__(screen, serial, instance, is_joint_mode) - self.screen_width = screen.get_width() - self.screen_height = screen.get_height() + self.player_score = 0 self.ai_score = 0 self.score_display_time = 0 @@ -28,6 +27,22 @@ class Pong(GameBase): self.reset() def reset(self): + global PADDLE_WIDTH, PADDLE_HEIGHT, BALL_SIZE, PADDLE_SPEED, AI_SPEED, BALL_SPEED + + scale_factor = min(self.screen_width / 640, self.screen_height / 480) + + if self.is_vertical: + PADDLE_WIDTH = min(100, int(80 * scale_factor)) + PADDLE_SPEED = max(5, min(8, int(8 * scale_factor))) + else: + PADDLE_WIDTH = min(100, int(100 * scale_factor)) + PADDLE_SPEED = max(8, min(10, int(10 * scale_factor))) + + PADDLE_HEIGHT = max(8, int(10 * scale_factor)) + BALL_SIZE = max(6, int(10 * scale_factor)) + AI_SPEED = max(3, min(4, int(4 * scale_factor))) + BALL_SPEED = max(4, min(5, int(5 * scale_factor))) + self.player_paddle = [ self.screen_width // 2 - PADDLE_WIDTH // 2, self.screen_height - 40, @@ -113,6 +128,8 @@ class Pong(GameBase): return None def update(self): + self.update_screen_dimensions() + if self.score_display_time: self.screen.fill(BLACK) @@ -122,26 +139,27 @@ class Pong(GameBase): f"Your Score: {self.player_score}", True, WHITE ) ai_score_text = self.font.render(f"AI Score: {self.ai_score}", True, WHITE) + vertical_spacing = 30 if self.is_vertical else 20 self.screen.blit( result_display, ( self.screen_width // 2 - result_display.get_width() // 2, - self.screen_height // 2 - 40, + self.screen_height // 2 - vertical_spacing * 2, ), ) self.screen.blit( player_score_text, ( self.screen_width // 2 - player_score_text.get_width() // 2, - self.screen_height // 2 - 20, + self.screen_height // 2, ), ) self.screen.blit( ai_score_text, ( self.screen_width // 2 - ai_score_text.get_width() // 2, - self.screen_height // 2 + 20, + self.screen_height // 2 + vertical_spacing, ), ) pygame.display.flip() @@ -226,8 +244,19 @@ class Pong(GameBase): f"AI: {self.ai_score}", True, WHITE ) - self.screen.blit(player_score_text, (10, self.screen_height - 40)) - self.screen.blit(ai_score_text, (10, 10)) + if self.is_vertical: + self.screen.blit( + player_score_text, + (self.screen_width // 2 - player_score_text.get_width() // 2, + self.screen_height - 40) + ) + self.screen.blit( + ai_score_text, + (self.screen_width // 2 - ai_score_text.get_width() // 2, 10) + ) + else: + self.screen.blit(player_score_text, (10, self.screen_height - 40)) + self.screen.blit(ai_score_text, (10, 10)) pygame.display.flip() clock.tick(60) diff --git a/src/splitscreen_duo/games/snake.py b/src/splitscreen_duo/games/snake.py index 83ee987..11b66f7 100644 --- a/src/splitscreen_duo/games/snake.py +++ b/src/splitscreen_duo/games/snake.py @@ -17,12 +17,15 @@ logger = logging.getLogger(__name__) class Snake(GameBase): def __init__(self, screen, serial, instance, is_joint_mode=False): super().__init__(screen, serial, instance, is_joint_mode) - self.screen_width = screen.get_width() - self.screen_height = screen.get_height() self.reset() def reset(self): + global BLOCK_SIZE, SPEED + + min_dimension = min(self.screen_width, self.screen_height) + BLOCK_SIZE = max(10, min(20, min_dimension // 30)) + SPEED = 15 if self.screen_width >= 400 else 12 self.body = [ [ self.screen_width // 2 - self.screen_width // 2 % BLOCK_SIZE, @@ -143,7 +146,10 @@ class Snake(GameBase): if not self.is_joint_mode or self.instance != "primary": score_text = self.font.render(f"Score: {self.score}", True, WHITE) - self.screen.blit(score_text, (10, 10)) + if self.is_vertical: + self.screen.blit(score_text, (self.screen_width // 2 - score_text.get_width() // 2, 10)) + else: + self.screen.blit(score_text, (10, 10)) pygame.display.flip() clock.tick(SPEED) diff --git a/src/splitscreen_duo/menu.py b/src/splitscreen_duo/menu.py index 18dcca6..bd292e7 100644 --- a/src/splitscreen_duo/menu.py +++ b/src/splitscreen_duo/menu.py @@ -13,15 +13,15 @@ IS_DEVELOPMENT_MODE = os.getenv("DEVELOPMENT", "").lower() != "" OPTIONS = Game.all() + ["Quit"] logger = logging.getLogger(__name__) WIDTH = HEIGHT = FONT = screen = selected_index = None +ORIGINAL_WIDTH = ORIGINAL_HEIGHT = None def init_display(): - global WIDTH, HEIGHT, FONT, screen, selected_index + global WIDTH, HEIGHT, FONT, screen, selected_index, ORIGINAL_WIDTH, ORIGINAL_HEIGHT - WIDTH, HEIGHT = ( - pygame.display.Info().current_w // 2, - pygame.display.Info().current_h // 2, - ) + ORIGINAL_WIDTH = pygame.display.Info().current_w // 2 + ORIGINAL_HEIGHT = pygame.display.Info().current_h // 2 + WIDTH, HEIGHT = ORIGINAL_WIDTH, ORIGINAL_HEIGHT FONT = pygame.font.Font(None, 36) screen = pygame.display.set_mode( (WIDTH, HEIGHT) if IS_DEVELOPMENT_MODE else (0, 0), @@ -30,17 +30,41 @@ def init_display(): selected_index = 0 -def draw_menu(): +def draw_menu(is_joint_mode=False): screen.fill(WHITE) + is_vertical = HEIGHT > WIDTH * 1.5 + start_y = 100 if is_vertical else 150 + spacing = 40 if is_vertical else 50 + title_text = FONT.render("SplitScreen Duo", True, BLACK) + + screen.blit(title_text, (WIDTH // 2 - title_text.get_width() // 2, start_y - 50)) + for i, option in enumerate(OPTIONS): text = FONT.render(option, True, BLACK if i != selected_index else (200, 0, 0)) - screen.blit(text, (WIDTH // 2 - text.get_width() // 2, 150 + i * 50)) + screen.blit(text, (WIDTH // 2 - text.get_width() // 2, start_y + i * spacing)) pygame.display.flip() +def set_screen_orientation(is_joint_mode): + global WIDTH, HEIGHT, screen, ORIGINAL_WIDTH, ORIGINAL_HEIGHT + + if is_joint_mode: + WIDTH = ORIGINAL_WIDTH + HEIGHT = ORIGINAL_HEIGHT * 2 + else: + WIDTH = ORIGINAL_WIDTH + HEIGHT = ORIGINAL_HEIGHT + + screen = pygame.display.set_mode( + (WIDTH, HEIGHT) if IS_DEVELOPMENT_MODE else (0, 0), + pygame.RESIZABLE if IS_DEVELOPMENT_MODE else pygame.FULLSCREEN, + ) + + logger.info(f"screen orientation changed to {'vertical' if is_joint_mode else 'horizontal'}") + def process_events(serial, instance, is_joint_mode): global selected_index @@ -84,7 +108,10 @@ def process_events(serial, instance, is_joint_mode): ): is_joint_mode[0] = not is_joint_mode[0] - logger.info(f"Toggled joint mode to {is_joint_mode[0]}") + if instance == "primary": + set_screen_orientation(is_joint_mode[0]) + + logger.info(f"toggled joint mode to {is_joint_mode[0]}") command = ( Command.ENTER_JOINT_MODE.value @@ -94,4 +121,6 @@ def process_events(serial, instance, is_joint_mode): serial.write(json.dumps({"command": command}).encode("utf-8")) + draw_menu(is_joint_mode[0] if isinstance(is_joint_mode, list) else is_joint_mode) + return None |