From 126991327510f498c90f152ae6b4ef8193789e28 Mon Sep 17 00:00:00 2001 From: Matteo Benedetto Date: Tue, 19 Aug 2025 18:59:06 +0200 Subject: [PATCH] Refactor key handling and add keybindings configuration for game actions --- conf/keybinding_game.json | 4 ++-- conf/keybindings.yaml | 19 +++++++++++++++++++ engine/controls.py | 36 ++++++++++++++++++++++++++++++++---- engine/sdl2.py | 26 ++++++++++++++------------ rats.py | 11 ++++++++++- requirements.txt | 3 ++- 6 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 conf/keybindings.yaml diff --git a/conf/keybinding_game.json b/conf/keybinding_game.json index c6fa37e..ddc404c 100644 --- a/conf/keybinding_game.json +++ b/conf/keybinding_game.json @@ -1,10 +1,10 @@ { - "new_rat": ["Return", 13], + "new_rat": [["keyup", "Return"], ["keydown", "Return"]], "kill_rat": ["D"], "toggle_audio": ["M"], "toggle_full_screen": ["F"], - "scroll_up": ["Up", 8], + "scroll_up": [["keydown", "Up"], ["keydown", "Up"]], "scroll_down": ["Down", 9], "scroll_left": ["Left", 10], "scroll_right": ["Right", 11], diff --git a/conf/keybindings.yaml b/conf/keybindings.yaml new file mode 100644 index 0000000..034998f --- /dev/null +++ b/conf/keybindings.yaml @@ -0,0 +1,19 @@ +keybinding_game: + keydown_Return: spawn_rat + keydown_D: kill_rat + keydown_M: toggle_audio + keydown_F: toggle_full_screen + keydown_Up: start_scrolling|Up + keydown_Down: start_scrolling|Down + keydown_Left: start_scrolling|Left + keydown_Right: start_scrolling|Right + keyup_Up: stop_scrolling + keyup_Down: stop_scrolling + keyup_Left: stop_scrolling + keyup_Right: stop_scrolling + keydown_Space: spawn_new_bomb + keydown_N: spawn_nuclear_bomb + +keybinding_start_menu: + keydown_Return: reset_game + keydown_Escape: quit_game \ No newline at end of file diff --git a/engine/controls.py b/engine/controls.py index bc9e61d..b19f808 100644 --- a/engine/controls.py +++ b/engine/controls.py @@ -2,9 +2,38 @@ # The key_pressed method is called when a key is pressed, and it contains the logic for handling different key presses. import random +import yaml +# read yaml config file +bindings = {} +with open("conf/keybindings.yaml", "r") as f: + bindings = yaml.safe_load(f) + class KeyBindings: + def trigger(self, action): + print(f"Triggering action: {action}") + # Check if the action is in the bindings + if action in bindings[f"keybinding_{self.game_status}"]: + value = bindings[f"keybinding_{self.game_status}"][action] + # Call the corresponding method + if value: + print(f"Calling method: {value}") + if "|" in value: + method_name, *args = value.split("|") + method = getattr(self, method_name) + method(*args) + else: + getattr(self, value)() + else: + print(f"Action {action} not found in keybindings for {self.game_status}") + return + + print(f"Action {action} not found in keybindings for {self.game_status}") + return None def key_pressed(self, key, coords=None): + if key != "mouse": + key = [key, coords] + print(f"Key pressed: {key}") keybindings = self.configs[f"keybinding_{self.game_status}"] if key in keybindings.get("quit", []): self.render_engine.close() @@ -46,12 +75,11 @@ class KeyBindings: self.points = 0 self.start_game() + def spawn_new_bomb(self): + self.spawn_bomb(self.pointer) + def quit_game(self): self.render_engine.close() - def key_released(self, key): - if key in ["Up", "Down", "Left", "Right", 8, 9, 10, 11]: - self.stop_scrolling() - def start_scrolling(self, direction): self.scrolling_direction = direction if not self.scrolling: diff --git a/engine/sdl2.py b/engine/sdl2.py index d7ecd0e..72e9d64 100644 --- a/engine/sdl2.py +++ b/engine/sdl2.py @@ -68,7 +68,7 @@ class GameWindow: self.white_flash_opacity = 255 # Input handling - self.key_down, self.key_up, self.axis_scroll = key_callback + self.trigger = key_callback self.button_cursor = [0, 0] self.buttons = {} @@ -379,27 +379,29 @@ class GameWindow: for event in events: if event.type == sdl2.SDL_QUIT: self.running = False - elif event.type == sdl2.SDL_KEYDOWN and self.key_down: + elif event.type == sdl2.SDL_KEYDOWN: # print in file keycode keycode = event.key.keysym.sym - open("keycode.txt", "a").write(f"{keycode}\n") key = sdl2.SDL_GetKeyName(event.key.keysym.sym).decode('utf-8') # Check for Right Ctrl key to trigger white flash - if event.key.keysym.sym == sdl2.SDLK_RCTRL: - self.trigger_white_flash() - else: - self.key_down(key) - elif event.type == sdl2.SDL_KEYUP and self.key_up: + self.trigger(f"keydown_{key}") + elif event.type == sdl2.SDL_KEYUP: key = sdl2.SDL_GetKeyName(event.key.keysym.sym).decode('utf-8') - self.key_up(key) + self.trigger(f"keyup_{key}") elif event.type == sdl2.SDL_MOUSEMOTION: - self.key_down("mouse", coords=(event.motion.x, event.motion.y)) + self.trigger(f"mousemove_{event.motion.x}, {event.motion.y}") elif event.type == sdl2.SDL_JOYBUTTONDOWN: key = event.jbutton.button - self.key_down(key) + self.trigger(f"joybuttondown_{key}") elif event.type == sdl2.SDL_JOYBUTTONUP: key = event.jbutton.button - self.key_up(key) + self.trigger(f"joybuttonup_{key}") + elif event.type == sdl2.SDL_JOYHATMOTION: + hat = event.jhat.hat + value = event.jhat.value + self.trigger(f"joyhatmotion_{hat}_{value}") + + # Present the rendered frame self.renderer.present() diff --git a/rats.py b/rats.py index 38f2e29..d6947a7 100644 --- a/rats.py +++ b/rats.py @@ -22,7 +22,7 @@ class MiceMaze( self.full_screen = False self.render_engine = engine.GameWindow(self.map.width, self.map.height, self.cell_size, "Mice!", - key_callback=(self.key_pressed, self.key_released, self.axis_scroll)) + key_callback=self.trigger) self.load_assets() self.render_engine.window.show() self.pointer = (random.randint(1, self.map.width-2), random.randint(1, self.map.height-2)) @@ -68,6 +68,15 @@ class MiceMaze( self.background_texture = None for _ in range(5): self.spawn_rat() + + def reset_game(self): + self.pause = False + self.game_status = "game" + self.game_end = (False, None) + self.units.clear() + self.points = 0 + self.start_game() + # ==================== GAME LOGIC ==================== diff --git a/requirements.txt b/requirements.txt index c875f63..090618a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ pysdl2 -Pillow \ No newline at end of file +Pillow +pyaml \ No newline at end of file