refactor(game): use pygame.key.key_code()

This commit is contained in:
Kristofers Solo 2024-01-07 17:14:09 +02:00
parent 1cc0b081ec
commit f85b72a150
7 changed files with 130 additions and 115 deletions

View File

@ -3,17 +3,23 @@ pause = ["esc", "F1"]
quit = ["q"] quit = ["q"]
[Movement] [Movement]
left = ["left", "kp4"] left = ["left", "keypad 4"]
right = ["right", "kp6"] right = ["right", "keypad 6"]
down = ["down", "kp2"] down = ["down", "keypad 2"]
[Rotation] [Rotation]
cw = ["x", "up", "kp1", "kp5", "kp9"] # clockwise cw = ["x", "up", "keypad 1", "keypad 5", "keypad 9"] # clockwise
ccw = ["ctrl", "z", "kp3", "kp7"] # counter-clockwise ccw = [
"left ctrl",
"right ctrl",
"z",
"keypad 3",
"keypad 7",
] # counter-clockwise
[Action] [Action]
hold = ["shift", "c", "kp0"] hold = ["shift", "c", "keypad 0"]
drop = ["space", "kp5"] drop = ["space", "keypad 5"]
[Volume.Music] [Volume.Music]
enabled = true enabled = true

View File

@ -2,13 +2,14 @@ import sys
from typing import Optional from typing import Optional
import pygame import pygame
from utils import CONFIG, PYGAME_EVENT, GameMode, read_settings from utils import CONFIG, GameMode, read_settings
from game.log import log from game.log import log
from .base import BaseScreen, SceenElement, TextScreen from .base import BaseScreen, SceenElement, TextScreen
from .button import Button from .button import Button
from .game import Game from .game import Game
from .settings import Settings
class Main(BaseScreen, SceenElement, TextScreen): class Main(BaseScreen, SceenElement, TextScreen):
@ -23,6 +24,7 @@ class Main(BaseScreen, SceenElement, TextScreen):
self.settings = read_settings() self.settings = read_settings()
self.game_mode = mode self.game_mode = mode
self.game: Optional[Game] = None self.game: Optional[Game] = None
self.settings_screen: Optional[Settings] = None
def draw(self) -> None: def draw(self) -> None:
"""Update the display.""" """Update the display."""
@ -38,7 +40,7 @@ class Main(BaseScreen, SceenElement, TextScreen):
self.exit() self.exit()
elif event.type == pygame.KEYDOWN: elif event.type == pygame.KEYDOWN:
if event.key in [ 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() self.exit()
@ -73,11 +75,16 @@ class Main(BaseScreen, SceenElement, TextScreen):
self.game = Game(self.game_mode, self.settings) self.game = Game(self.game_mode, self.settings)
return self return self
def open_settings(self) -> "Main":
self._draw_background()
self.settings_screen = Settings()
return self
def _set_buttons(self) -> None: def _set_buttons(self) -> None:
self.buttons: list[Button] = [ self.buttons: list[Button] = [
Button("Play", self.play), Button("Play", self.play),
Button("AI", None), Button("AI", None),
Button("Settings", None), Button("Settings", self.open_settings),
Button("Quit", self.exit), Button("Quit", self.exit),
] ]

View File

@ -40,7 +40,7 @@ class Score(BaseScreen, SceenElement, TextScreen):
score (int): Current game score. score (int): Current game score.
level (int): Current game level. level (int): Current game level.
""" """
self.text: list[tuple[str, int], ...] = [ self.text: list[tuple[str, int]] = [
("Score", score), ("Score", score),
("Level", level), ("Level", level),
("Lines", lines), ("Lines", lines),

View File

@ -8,4 +8,92 @@ from .button import Button
class Settings(BaseScreen, SceenElement, TextScreen): 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)

View File

@ -2,7 +2,7 @@ from typing import Any, Callable, Optional
import numpy as np import numpy as np
import pygame 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.log import log
from game.sprites import Block, Tetromino from game.sprites import Block, Tetromino
@ -366,10 +366,14 @@ class Tetris(BaseScreen):
See `settings.toml` for the default key bindings. 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) 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) left_key_pressed = any(keys[key] for key in left_keys)
if not self.timers.horizontal.active: if not self.timers.horizontal.active:
@ -386,10 +390,12 @@ class Tetris(BaseScreen):
See `settings.toml` for the default key bindings. 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) 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) ccw_key_pressed = any(keys[key] for key in ccw_keys)
if not self.timers.rotation.active: if not self.timers.rotation.active:
@ -407,7 +413,9 @@ class Tetris(BaseScreen):
See `settings.toml` for the default key bindings. 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) down_key_pressed = any(keys[key] for key in down_keys)
if not self.down_pressed and down_key_pressed: if not self.down_pressed and down_key_pressed:
self.down_pressed = True self.down_pressed = True
@ -423,7 +431,9 @@ class Tetris(BaseScreen):
See `settings.toml` for the default key bindings. 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) drop_key_pressed = any(keys[key] for key in drop_keys)
if not self.timers.drop.active and drop_key_pressed: if not self.timers.drop.active and drop_key_pressed:

View File

@ -1,6 +1,5 @@
from .config import CONFIG from .config import CONFIG
from .enum import Direction, GameMode, Rotation from .enum import Direction, GameMode, Rotation
from .events import PYGAME_EVENT
from .figure import Figure, FigureConfig from .figure import Figure, FigureConfig
from .log import log from .log import log
from .path import BASE_PATH from .path import BASE_PATH
@ -19,5 +18,4 @@ __all__ = [
"GameMode", "GameMode",
"read_settings", "read_settings",
"save_settings", "save_settings",
"PYGAME_EVENT",
] ]

View File

@ -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,
}