diff --git a/.gitignore b/.gitignore index 874e073..573ed1c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,6 @@ dist/ rats rats.spec .env -release/ \ No newline at end of file +release/ +unit/__pycache__ +conf/keybindings.yaml \ No newline at end of file diff --git a/conf/keybinding_game.json b/conf/keybinding_game.json deleted file mode 100644 index ddc404c..0000000 --- a/conf/keybinding_game.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - - "new_rat": [["keyup", "Return"], ["keydown", "Return"]], - "kill_rat": ["D"], - "toggle_audio": ["M"], - "toggle_full_screen": ["F"], - "scroll_up": [["keydown", "Up"], ["keydown", "Up"]], - "scroll_down": ["Down", 9], - "scroll_left": ["Left", 10], - "scroll_right": ["Right", 11], - "spawn_bomb": ["Space", 1], - "spawn_mine": ["Left Ctrl", 2, 17], - "spawn_nuclear_bomb": ["N", 3], - "pause": ["P", 16] -} \ No newline at end of file diff --git a/conf/keybinding_paused.json b/conf/keybinding_paused.json deleted file mode 100644 index 6ee1b3e..0000000 --- a/conf/keybinding_paused.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - - "reset_game": ["Return", 13], - "pause": ["P", 16], - "quit": ["Q", 12] -} \ No newline at end of file diff --git a/conf/keybinding_start_menu.json b/conf/keybinding_start_menu.json deleted file mode 100644 index e392d3f..0000000 --- a/conf/keybinding_start_menu.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - - "start_game": ["Return", 13], - "toggle_full_screen": ["F"], - "quit": ["Q", 12] -} \ No newline at end of file diff --git a/conf/keybindings.yaml b/conf/keybindings.yaml index 034998f..3ad3a5c 100644 --- a/conf/keybindings.yaml +++ b/conf/keybindings.yaml @@ -12,8 +12,18 @@ keybinding_game: keyup_Left: stop_scrolling keyup_Right: stop_scrolling keydown_Space: spawn_new_bomb - keydown_N: spawn_nuclear_bomb + keydown_N: spawn_new_nuclear_bomb + keydown_Left_Ctrl: spawn_new_mine + keydown_P: toggle_pause keybinding_start_menu: keydown_Return: reset_game - keydown_Escape: quit_game \ No newline at end of file + keydown_Escape: quit_game + keydown_M: toggle_audio + keydown_F: toggle_full_screen + +keybinding_paused: + keydown_Return: reset_game + keydown_Escape: quit_game + keydown_M: toggle_audio + keydown_F: toggle_full_screen \ No newline at end of file diff --git a/conf/keybindings_pc.yaml b/conf/keybindings_pc.yaml new file mode 100644 index 0000000..3ad3a5c --- /dev/null +++ b/conf/keybindings_pc.yaml @@ -0,0 +1,29 @@ +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_new_nuclear_bomb + keydown_Left_Ctrl: spawn_new_mine + keydown_P: toggle_pause + +keybinding_start_menu: + keydown_Return: reset_game + keydown_Escape: quit_game + keydown_M: toggle_audio + keydown_F: toggle_full_screen + +keybinding_paused: + keydown_Return: reset_game + keydown_Escape: quit_game + keydown_M: toggle_audio + keydown_F: toggle_full_screen \ No newline at end of file diff --git a/conf/keybindings_r36s.yaml b/conf/keybindings_r36s.yaml new file mode 100644 index 0000000..5558f37 --- /dev/null +++ b/conf/keybindings_r36s.yaml @@ -0,0 +1,24 @@ +keybinding_game: + joybuttondown_13: spawn_rat + joybuttondown_8: start_scrolling|Up + joybuttondown_9: start_scrolling|Down + joybuttondown_10: start_scrolling|Left + joybuttondown_11: start_scrolling|Right + joybuttonup_8: stop_scrolling + joybuttonup_9: stop_scrolling + joybuttonup_10: stop_scrolling + joybuttonup_11: stop_scrolling + joybuttondown_1: spawn_new_bomb + joybuttondown_3: spawn_new_nuclear_bomb + joybuttondown_2: spawn_new_mine + joybuttondown_16: toggle_pause + +keybinding_start_menu: + joybuttondown_13: reset_game + joybuttondown_16: toggle_pause + joybuttondown_12: quit_game + +keybinding_paused: + joybuttondown_13: reset_game + joybuttondown_16: toggle_pause + joybuttondown_12: quit_game diff --git a/engine/controls.py b/engine/controls.py index b19f808..2efca30 100644 --- a/engine/controls.py +++ b/engine/controls.py @@ -11,73 +11,44 @@ with open("conf/keybindings.yaml", "r") as f: class KeyBindings: def trigger(self, action): - print(f"Triggering action: {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}") + #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}") + #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}") + #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() - elif key in keybindings.get("new_rat", []): - self.spawn_rat() - elif key in keybindings.get("kill_rat", []): - if self.units: - self.units[random.choice(list(self.units.keys()))].die(score=5) - elif key in keybindings.get("toggle_audio", []): - self.audio = not self.audio - elif key in keybindings.get("toggle_full_screen", []): - self.full_screen = not self.full_screen - self.render_engine.full_screen(self.full_screen) - elif key in keybindings.get("scroll_up", []): - self.start_scrolling("Up") - elif key in keybindings.get("scroll_down", []): - self.start_scrolling("Down") - elif key in keybindings.get("scroll_left", []): - self.start_scrolling("Left") - elif key in keybindings.get("scroll_right", []): - self.start_scrolling("Right") - elif key in keybindings.get("spawn_bomb", []): - self.spawn_bomb(self.pointer) - elif key in keybindings.get("spawn_mine", []): - self.spawn_mine(self.pointer) - elif key in keybindings.get("spawn_nuclear_bomb", []): - self.spawn_nuclear_bomb(self.pointer) - elif key in keybindings.get("pause", []): - self.game_status = "paused" if self.game_status == "game" else "game" - elif key in keybindings.get("start_game", []): - self.pause = False - self.game_status = "game" - self.start_game() - elif key in keybindings.get("reset_game", []): - self.pause = False - self.game_status = "game" - self.game_end = (False, None) - self.units.clear() - self.points = 0 - self.start_game() def spawn_new_bomb(self): self.spawn_bomb(self.pointer) - + + def spawn_new_mine(self): + self.spawn_mine(self.pointer) + + def spawn_new_nuclear_bomb(self): + self.spawn_nuclear_bomb(self.pointer) + + def toggle_audio(self): + self.render_engine.audio = not self.render_engine.audio + def toggle_pause(self): + self.game_status = "paused" if self.game_status == "game" else "game" + + def toggle_full_screen(self): + self.full_screen = not self.full_screen + self.render_engine.full_screen(self.full_screen) + def quit_game(self): self.render_engine.close() def start_scrolling(self, direction): diff --git a/engine/sdl2.py b/engine/sdl2.py index 72e9d64..d6738cd 100644 --- a/engine/sdl2.py +++ b/engine/sdl2.py @@ -74,7 +74,7 @@ class GameWindow: # Audio system initialization self._init_audio_system() - + self.audio = True # Input devices self.load_joystick() @@ -279,7 +279,7 @@ class GameWindow: self.renderer.copy(self.ammo_background, dstrect=sdl2.SDL_Rect(position[0] - 5, position[1] - 2, text_width + 10, text_height + 4)) self.renderer.copy(self.ammo_sprite, dstrect=sdl2.SDL_Rect(position[0], position[1], text_width, text_height)) self.renderer.copy(assets["BMP_BOMB0"], dstrect=sdl2.SDL_Rect(position[0]+25, position[1], 20, 20)) - self.renderer.copy(assets["mine"], dstrect=sdl2.SDL_Rect(position[0]+80, position[1], 20, 20)) + self.renderer.copy(assets["BMP_POISON"], dstrect=sdl2.SDL_Rect(position[0]+80, position[1], 20, 20)) self.renderer.copy(assets["BMP_NUCLEAR"], dstrect=sdl2.SDL_Rect(position[0]+130, position[1], 20, 20)) # ====================== # VIEW & NAVIGATION @@ -319,6 +319,8 @@ class GameWindow: def play_sound(self, sound_file, tag="base"): """Play a sound file on the specified audio channel""" + if not self.audio: + return sound_path = os.path.join("sound", sound_file) rw = sdl2.SDL_RWFromFile(byteify(sound_path, "utf-8"), b"rb") if not rw: @@ -383,10 +385,12 @@ class GameWindow: # print in file keycode keycode = event.key.keysym.sym key = sdl2.SDL_GetKeyName(event.key.keysym.sym).decode('utf-8') + key = key.replace(" ", "_") # Check for Right Ctrl key to trigger white flash self.trigger(f"keydown_{key}") elif event.type == sdl2.SDL_KEYUP: key = sdl2.SDL_GetKeyName(event.key.keysym.sym).decode('utf-8') + key = key.replace(" ", "_") self.trigger(f"keyup_{key}") elif event.type == sdl2.SDL_MOUSEMOTION: self.trigger(f"mousemove_{event.motion.x}, {event.motion.y}") diff --git a/engine/unit_manager.py b/engine/unit_manager.py index fa7453e..db6f18b 100644 --- a/engine/unit_manager.py +++ b/engine/unit_manager.py @@ -1,6 +1,6 @@ import random import uuid -from units import rat, bomb, mine +from units import rat, bomb, mine, points class UnitManager: def count_rats(self): diff --git a/rats.py b/rats.py index d6947a7..fadb405 100644 --- a/rats.py +++ b/rats.py @@ -5,6 +5,7 @@ import os import json from engine import maze, sdl2 as engine, controls, graphics, unit_manager, scoring +from units import points class MiceMaze( controls.KeyBindings, @@ -118,7 +119,7 @@ class MiceMaze( def run(self): self.render_engine.mainloop(update=self.update_maze, bg_update=self.draw_maze) - + # ==================== GAME OVER LOGIC ==================== def game_over(self): @@ -137,7 +138,7 @@ class MiceMaze( self.game_end = (True, False) self.game_status = "paused" return True - if not count_rats: + if not count_rats and not any(isinstance(unit, points.Point) for unit in self.units.values()): self.render_engine.stop_sound() self.render_engine.play_sound("VICTORY.WAV") self.render_engine.play_sound("WELLDONE.WAV", tag="effects") diff --git a/units/__pycache__/rat.cpython-313.pyc b/units/__pycache__/rat.cpython-313.pyc index bb861f2..e6190f9 100644 Binary files a/units/__pycache__/rat.cpython-313.pyc and b/units/__pycache__/rat.cpython-313.pyc differ diff --git a/units/__pycache__/unit.cpython-313.pyc b/units/__pycache__/unit.cpython-313.pyc index df01ebe..9ed59d2 100644 Binary files a/units/__pycache__/unit.cpython-313.pyc and b/units/__pycache__/unit.cpython-313.pyc differ diff --git a/units/mine.py b/units/mine.py index d0c380d..9c4f59d 100644 --- a/units/mine.py +++ b/units/mine.py @@ -26,9 +26,8 @@ class Mine(Unit): """Mine explodes, killing the rat and destroying itself.""" if not self.armed: return - - print("MINE EXPLOSION!") - self.game.render_engine.play_sound("BOMB.WAV") + + self.game.render_engine.play_sound("POISON.WAV") # Kill the rat that stepped on the mine if victim_rat.id in self.game.units: @@ -43,7 +42,7 @@ class Mine(Unit): return # Use mine asset - image = self.game.assets["mine"] + image = self.game.assets["BMP_POISON"] image_size = self.game.render_engine.get_image_size(image) # Center the mine in the cell @@ -55,5 +54,4 @@ class Mine(Unit): def die(self, score=None): """Remove mine from game and disarm it.""" self.armed = False - Explosion(self.game, self.position).draw() super().die(score)