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"]
[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

View File

@ -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),
]

View File

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

View File

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

View File

@ -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",
]

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