From f85b72a1500cb95fb952347d2fc90f136942a2d2 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 7 Jan 2024 17:14:09 +0200 Subject: [PATCH] refactor(game): use `pygame.key.key_code()` --- settings.toml | 20 +++++--- src/game/screens/main.py | 13 +++-- src/game/screens/score.py | 2 +- src/game/screens/settings.py | 90 +++++++++++++++++++++++++++++++++- src/game/screens/tetris.py | 24 ++++++--- src/utils/__init__.py | 2 - src/utils/events.py | 94 ------------------------------------ 7 files changed, 130 insertions(+), 115 deletions(-) delete mode 100644 src/utils/events.py diff --git a/settings.toml b/settings.toml index 47b2aaf..ccda425 100644 --- a/settings.toml +++ b/settings.toml @@ -3,17 +3,23 @@ pause = ["esc", "F1"] quit = ["q"] [Movement] -left = ["left", "kp4"] -right = ["right", "kp6"] -down = ["down", "kp2"] +left = ["left", "keypad 4"] +right = ["right", "keypad 6"] +down = ["down", "keypad 2"] [Rotation] -cw = ["x", "up", "kp1", "kp5", "kp9"] # clockwise -ccw = ["ctrl", "z", "kp3", "kp7"] # counter-clockwise +cw = ["x", "up", "keypad 1", "keypad 5", "keypad 9"] # clockwise +ccw = [ + "left ctrl", + "right ctrl", + "z", + "keypad 3", + "keypad 7", +] # counter-clockwise [Action] -hold = ["shift", "c", "kp0"] -drop = ["space", "kp5"] +hold = ["shift", "c", "keypad 0"] +drop = ["space", "keypad 5"] [Volume.Music] enabled = true diff --git a/src/game/screens/main.py b/src/game/screens/main.py index 573e05f..fbd1590 100644 --- a/src/game/screens/main.py +++ b/src/game/screens/main.py @@ -2,13 +2,14 @@ import sys from typing import Optional import pygame -from utils import CONFIG, PYGAME_EVENT, GameMode, read_settings +from utils import CONFIG, GameMode, read_settings from game.log import log from .base import BaseScreen, SceenElement, TextScreen from .button import Button from .game import Game +from .settings import Settings class Main(BaseScreen, SceenElement, TextScreen): @@ -23,6 +24,7 @@ class Main(BaseScreen, SceenElement, TextScreen): self.settings = read_settings() self.game_mode = mode self.game: Optional[Game] = None + self.settings_screen: Optional[Settings] = None def draw(self) -> None: """Update the display.""" @@ -38,7 +40,7 @@ class Main(BaseScreen, SceenElement, TextScreen): self.exit() elif event.type == pygame.KEYDOWN: if event.key in [ - PYGAME_EVENT[key] for key in self.settings["General"]["quit"] + pygame.key.key_code(key) for key in self.settings["General"]["quit"] ]: self.exit() @@ -73,11 +75,16 @@ class Main(BaseScreen, SceenElement, TextScreen): self.game = Game(self.game_mode, self.settings) return self + def open_settings(self) -> "Main": + self._draw_background() + self.settings_screen = Settings() + return self + def _set_buttons(self) -> None: self.buttons: list[Button] = [ Button("Play", self.play), Button("AI", None), - Button("Settings", None), + Button("Settings", self.open_settings), Button("Quit", self.exit), ] diff --git a/src/game/screens/score.py b/src/game/screens/score.py index 903f318..227e885 100644 --- a/src/game/screens/score.py +++ b/src/game/screens/score.py @@ -40,7 +40,7 @@ class Score(BaseScreen, SceenElement, TextScreen): score (int): Current game score. level (int): Current game level. """ - self.text: list[tuple[str, int], ...] = [ + self.text: list[tuple[str, int]] = [ ("Score", score), ("Level", level), ("Lines", lines), diff --git a/src/game/screens/settings.py b/src/game/screens/settings.py index 285c83c..189f2e4 100644 --- a/src/game/screens/settings.py +++ b/src/game/screens/settings.py @@ -8,4 +8,92 @@ from .button import Button class Settings(BaseScreen, SceenElement, TextScreen): - pass + def __init__(self) -> None: + self._initialize_surface() + self._initialize_rect() + self._initialize_font() + self._set_buttons() + self._initialize_increment_height() + + def draw(self) -> None: + """Update the display.""" + self._draw_background() + self._draw_text() + + def run(self) -> None: + self.draw() + + def update(self) -> None: + pass + + def _draw_text(self) -> None: + """Draw the text on the score surface.""" + for idx, text in enumerate(self.text): + x = self.surface.get_width() / 2 + y = self.increment_height / 2 + idx * self.increment_height + self._display_text(text, pygame.Vector2(x, y)) + + def _display_text(self, text_value: tuple[str, int], pos: pygame.Vector2) -> None: + """ + Display a single text element on the score surface. + + Args: + text_value: A tuple containing the label and value of the text element. + pos: The position (x, y) where the text should be displayed. + """ + + text, value = text_value + + if len(text) >= 10: + text_surface = self.font.render(f"{text}:", True, CONFIG.colors.fg_sidebar) + + value_surface = self.font.render(f"{value}", True, CONFIG.colors.fg_sidebar) + value_rect = value_surface.get_rect(center=(pos.x, pos.y + 40)) + + self.surface.blit(value_surface, value_rect) + else: + text_surface = self.font.render( + f"{text}:{value}", True, CONFIG.colors.fg_sidebar + ) + text_rect = text_surface.get_rect(center=pos) + self.surface.blit(text_surface, text_rect) + + text_rect = text_surface.get_rect(center=pos) + self.surface.blit(text_surface, text_rect) + + def _draw_border(self) -> None: + """Draw the border of the score surface.""" + pygame.draw.rect( + self.display_surface, + CONFIG.colors.border_highlight, + self.rect, + CONFIG.game.line_width * 2, + CONFIG.game.border_radius, + ) + + def _draw_background(self) -> None: + """Fill the background of the score display.""" + self.surface.fill(CONFIG.colors.bg_sidebar) + + def _initialize_surface(self) -> None: + """Initialize the score surface.""" + self.surface = pygame.Surface(CONFIG.sidebar.score) + self.display_surface = pygame.display.get_surface() + + def _initialize_rect(self) -> None: + """Initialize the score rectangle.""" + self.rect = self.surface.get_rect( + bottomright=CONFIG.window.size - CONFIG.window.padding + ) + + def _initialize_font(self) -> None: + """Initialize the font used to display the score.""" + self.font = pygame.font.Font(CONFIG.font.family, CONFIG.font.size) + + def _initialize_increment_height(self) -> None: + """Initialize the increment height for positioning text elements.""" + self.increment_height = self.surface.get_height() / len(self.text) + + def _update_display_surface(self) -> None: + """Update the display surface.""" + self.display_surface.blit(self.surface, self.rect) diff --git a/src/game/screens/tetris.py b/src/game/screens/tetris.py index fd3367a..3c4b02e 100644 --- a/src/game/screens/tetris.py +++ b/src/game/screens/tetris.py @@ -2,7 +2,7 @@ from typing import Any, Callable, Optional import numpy as np import pygame -from utils import CONFIG, PYGAME_EVENT, Direction, Figure, GameMode, Rotation +from utils import CONFIG, Direction, Figure, GameMode, Rotation from game.log import log from game.sprites import Block, Tetromino @@ -366,10 +366,14 @@ class Tetris(BaseScreen): See `settings.toml` for the default key bindings. """ - right_keys = [PYGAME_EVENT[key] for key in self.settings["Movement"]["right"]] + right_keys = [ + pygame.key.key_code(key) for key in self.settings["Movement"]["right"] + ] right_key_pressed = any(keys[key] for key in right_keys) - left_keys = [PYGAME_EVENT[key] for key in self.settings["Movement"]["left"]] + left_keys = [ + pygame.key.key_code(key) for key in self.settings["Movement"]["left"] + ] left_key_pressed = any(keys[key] for key in left_keys) if not self.timers.horizontal.active: @@ -386,10 +390,12 @@ class Tetris(BaseScreen): See `settings.toml` for the default key bindings. """ - cw_keys = [PYGAME_EVENT[key] for key in self.settings["Rotation"]["cw"]] + cw_keys = [pygame.key.key_code(key) for key in self.settings["Rotation"]["cw"]] cw_key_pressed = any(keys[key] for key in cw_keys) - ccw_keys = [PYGAME_EVENT[key] for key in self.settings["Rotation"]["ccw"]] + ccw_keys = [ + pygame.key.key_code(key) for key in self.settings["Rotation"]["ccw"] + ] ccw_key_pressed = any(keys[key] for key in ccw_keys) if not self.timers.rotation.active: @@ -407,7 +413,9 @@ class Tetris(BaseScreen): See `settings.toml` for the default key bindings. """ - down_keys = [PYGAME_EVENT[key] for key in self.settings["Movement"]["down"]] + down_keys = [ + pygame.key.key_code(key) for key in self.settings["Movement"]["down"] + ] down_key_pressed = any(keys[key] for key in down_keys) if not self.down_pressed and down_key_pressed: self.down_pressed = True @@ -423,7 +431,9 @@ class Tetris(BaseScreen): See `settings.toml` for the default key bindings. """ - drop_keys = [PYGAME_EVENT[key] for key in self.settings["Action"]["drop"]] + drop_keys = [ + pygame.key.key_code(key) for key in self.settings["Action"]["drop"] + ] drop_key_pressed = any(keys[key] for key in drop_keys) if not self.timers.drop.active and drop_key_pressed: diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 38d1538..2d4dc42 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -1,6 +1,5 @@ from .config import CONFIG from .enum import Direction, GameMode, Rotation -from .events import PYGAME_EVENT from .figure import Figure, FigureConfig from .log import log from .path import BASE_PATH @@ -19,5 +18,4 @@ __all__ = [ "GameMode", "read_settings", "save_settings", - "PYGAME_EVENT", ] diff --git a/src/utils/events.py b/src/utils/events.py deleted file mode 100644 index 1e56eac..0000000 --- a/src/utils/events.py +++ /dev/null @@ -1,94 +0,0 @@ -import pygame - -PYGAME_EVENT: dict[str, int] = { - "up": pygame.K_UP, - "down": pygame.K_DOWN, - "left": pygame.K_LEFT, - "right": pygame.K_RIGHT, - "space": pygame.K_SPACE, - "escape": pygame.K_ESCAPE, - "q": pygame.K_q, - "w": pygame.K_w, - "e": pygame.K_e, - "r": pygame.K_r, - "t": pygame.K_t, - "y": pygame.K_y, - "u": pygame.K_u, - "i": pygame.K_i, - "o": pygame.K_o, - "p": pygame.K_p, - "a": pygame.K_a, - "s": pygame.K_s, - "d": pygame.K_d, - "f": pygame.K_f, - "g": pygame.K_g, - "h": pygame.K_h, - "j": pygame.K_j, - "k": pygame.K_k, - "l": pygame.K_l, - "z": pygame.K_z, - "x": pygame.K_x, - "c": pygame.K_c, - "v": pygame.K_v, - "b": pygame.K_b, - "n": pygame.K_n, - "m": pygame.K_m, - "1": pygame.K_1, - "2": pygame.K_2, - "3": pygame.K_3, - "4": pygame.K_4, - "5": pygame.K_5, - "6": pygame.K_6, - "7": pygame.K_7, - "8": pygame.K_8, - "9": pygame.K_9, - "0": pygame.K_0, - "shift": pygame.K_LSHIFT, - "ctrl": pygame.K_LCTRL, - "alt": pygame.K_LALT, - "tab": pygame.K_TAB, - "capslock": pygame.K_CAPSLOCK, - "return": pygame.K_RETURN, - "backspace": pygame.K_BACKSPACE, - "insert": pygame.K_INSERT, - "delete": pygame.K_DELETE, - "home": pygame.K_HOME, - "end": pygame.K_END, - "pageup": pygame.K_PAGEUP, - "pagedown": pygame.K_PAGEDOWN, - "numlock": pygame.K_NUMLOCK, - "printscreen": pygame.K_PRINTSCREEN, - "scrolllock": pygame.K_SCROLLLOCK, - "pause": pygame.K_PAUSE, - "F1": pygame.K_F1, - "F2": pygame.K_F2, - "F3": pygame.K_F3, - "F4": pygame.K_F4, - "F5": pygame.K_F5, - "F6": pygame.K_F6, - "F7": pygame.K_F7, - "F8": pygame.K_F8, - "F9": pygame.K_F9, - "F10": pygame.K_F10, - "F11": pygame.K_F11, - "F12": pygame.K_F12, - "F13": pygame.K_F13, - "F14": pygame.K_F14, - "F15": pygame.K_F15, - "kp0": pygame.K_KP0, - "kp1": pygame.K_KP1, - "kp2": pygame.K_KP2, - "kp3": pygame.K_KP3, - "kp4": pygame.K_KP4, - "kp5": pygame.K_KP5, - "kp6": pygame.K_KP6, - "kp7": pygame.K_KP7, - "kp8": pygame.K_KP8, - "kp9": pygame.K_KP9, - "kp_divide": pygame.K_KP_DIVIDE, - "kp_multiply": pygame.K_KP_MULTIPLY, - "kp_minus": pygame.K_KP_MINUS, - "kp_plus": pygame.K_KP_PLUS, - "kp_enter": pygame.K_KP_ENTER, - "kp_equals": pygame.K_KP_EQUALS, -}