Aggiungi file di configurazione per i binding dei tasti e implementa la gestione degli input nel gioco

This commit is contained in:
2024-12-27 19:03:04 +01:00
parent ccf7769979
commit 98a9e5fb8b
12 changed files with 85 additions and 56 deletions
+13
View File
@@ -0,0 +1,13 @@
{
"quit": ["Q", 12],
"new_rat": ["Return", 13],
"kill_rat": ["D"],
"toggle_audio": ["M"],
"toggle_full_screen": ["F"],
"scroll_up": ["Up", 8],
"scroll_down": ["Down", 9],
"scroll_left": ["Left", 10],
"scroll_right": ["Right", 11],
"spawn_bomb": ["Space", 1],
"pause": ["P", 16]
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

+15 -18
View File
@@ -5,37 +5,34 @@ import random
class KeyBindings:
def key_pressed(self, key, coords=None):
#print(key)
if key == "Q" or key == 12:
if key in self.keybindings["quit"]:
self.engine.close()
elif key == "Return" or key == 13:
elif key in self.keybindings["new_rat"]:
self.new_rat()
elif key == "D":
elif key in self.keybindings["kill_rat"]:
if self.units:
self.units[random.choice(list(self.units.keys()))].die(score=5)
elif key == "M":
elif key in self.keybindings["toggle_audio"]:
self.audio = not self.audio
elif key == "F":
elif key in self.keybindings["toggle_full_screen"]:
self.full_screen = not self.full_screen
self.engine.full_screen(self.full_screen)
elif key == "Up" or key == 8:
elif key in self.keybindings["scroll_up"]:
self.start_scrolling("Up")
elif key == "Down" or key == 9:
elif key in self.keybindings["scroll_down"]:
self.start_scrolling("Down")
elif key == "Left" or key == 10:
elif key in self.keybindings["scroll_left"]:
self.start_scrolling("Left")
elif key == "Right" or key == 11:
elif key in self.keybindings["scroll_right"]:
self.start_scrolling("Right")
elif key == "Space" or key == 1:
self.play_sound("PUTDOWN.WAV")
elif key in self.keybindings["spawn_bomb"]:
self.play_sound("PUTDOWN.WAV", tag="effects")
self.spawn_bomb(self.pointer)
elif key == "P" or key == 16:
elif key in self.keybindings["pause"]:
self.pause = not self.pause
# elif key == "mouse":
# adjusted_coords = (coords[0]//self.cell_size*2, coords[1]//self.cell_size*2)
# self.pointer = adjusted_coords
# self.scroll_cursor()
def quit_game(self):
self.engine.close()
def key_released(self, key):
if key in ["Up", "Down", "Left", "Right", 8, 9, 10, 11]:
self.stop_scrolling()
+32 -19
View File
@@ -7,7 +7,7 @@ from ctypes import *
from PIL import Image
from sdl2 import SDL_AudioSpec
import random
class GameWindow:
def __init__(self, width, height, cell_size, title="Default", key_callback=None):
@@ -23,6 +23,7 @@ class GameWindow:
self.h_offset = self.h_start_offset
self.max_w_offset = self.target_size[0] - self.width
self.max_h_offset = self.target_size[1] - self.height
self.scale = self.target_size[1] // self.cell_size
print(f"Screen size: {self.width}x{self.height}")
sdl2.ext.init(joystick=True)
sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO)
@@ -37,11 +38,12 @@ class GameWindow:
self.running = True
self.key_down, self.key_up, self.axis_scroll = key_callback
self.performance = 0
self.audio_devs = []
#for i in range(5):
# self.audio_devs.append((True, sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0)))
self.audio_dev = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0)
self.audio_devs = {}
self.button_cursor = [0, 0]
self.buttons = {}
self.audio_devs["base"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0)
self.audio_devs["effects"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0)
self.audio_devs["music"] = sdl2.SDL_OpenAudioDevice(None, 0, SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048), None, 0)
def create_texture(self, tiles: list):
bg_surface = sdl2.SDL_CreateRGBSurface(0, self.width, self.height, 32, 0, 0, 0, 0)
for tile in tiles:
@@ -97,8 +99,8 @@ class GameWindow:
sprite.position = (x+self.w_offset, y+self.h_offset)
self.renderer.copy(sprite, dstrect=sprite.position)
def draw_rectangle(self, x, y, width, height, tag, outline="red", filling=None):
x, y = x + self.w_offset, y + self.h_offset
if filling:
self.renderer.fill((x, y, width, height), sdl2.ext.Color(*filling))
else:
@@ -113,8 +115,8 @@ class GameWindow:
def delete_tag(self, tag):
pass
def win_screen(self, text, **kwargs):
self.draw_rectangle(50 - self.w_offset, 50 - self.h_offset,
def dialog(self, text, **kwargs):
self.draw_rectangle(50, 50,
self.target_size[0] - 100, self.target_size[1] - 100, "win", filling=(255, 255, 255))
self.draw_text(text, self.fonts[self.target_size[1]//20], "center", sdl2.ext.Color(0, 0, 0))
if image := kwargs.get("image"):
@@ -133,11 +135,7 @@ class GameWindow:
sprite_score.position = (self.target_size[0] // 2 - 50-sprite_score.size[0] // 4,
self.target_size[1] // 2 + 60 + 20 * (i + 1))
self.renderer.copy(sprite_score, dstrect=sprite_score.position)
def pause_screen(self, text):
self.draw_rectangle(50 - self.w_offset, 50 - self.h_offset,
self.target_size[0] - 100, self.target_size[1] - 100, "pause", filling=(255, 255, 255))
self.draw_text(text, self.fonts[self.target_size[1]//20], "center", sdl2.ext.Color(0, 0, 0))
def get_image_size(self, image):
return image.size
@@ -159,6 +157,9 @@ class GameWindow:
def is_in_visible_area(self, x, y):
return -self.w_offset -self.cell_size <= x <= self.width - self.w_offset and -self.h_offset -self.cell_size <= y <= self.height - self.h_offset
def get_perf_counter(self):
return sdl2.SDL_GetPerformanceCounter()
def mainloop(self, **kwargs):
while self.running:
performance_start = sdl2.SDL_GetPerformanceCounter()
@@ -228,7 +229,7 @@ class GameWindow:
self.w_offset = x
self.h_offset = y
def play_sound(self, sound_file):
def play_sound(self, sound_file, tag="base"):
print(sound_file)
sound_file = os.path.join("sound", sound_file)
rw = sdl2.SDL_RWFromFile(byteify(sound_file, "utf-8"), b"rb")
@@ -237,12 +238,12 @@ class GameWindow:
_buf = POINTER(sdl2.Uint8)()
_length = sdl2.Uint32()
spec = SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048)
spec = SDL_AudioSpec(freq=22050, aformat=sdl2.AUDIO_U8, channels=1, samples=2048)
if sdl2.SDL_LoadWAV_RW(rw, 1, byref(spec), byref(_buf), byref(_length)) == None:
raise RuntimeError("Failed to load WAV")
devid = self.audio_dev
sdl2.SDL_ClearQueuedAudio(devid)
devid = self.audio_devs[tag]
# Clear any queued audio
sdl2.SDL_ClearQueuedAudio(devid)
# Start playing audio
@@ -255,4 +256,16 @@ class GameWindow:
sdl2.SDL_PauseAudioDevice(dev[1], 1)
sdl2.SDL_ClearQueuedAudio(dev[1])
def start_dialog(self, **kwargs):
self.dialog("Welcome to the Mice!", **kwargs)
center = self.get_view_center()
self.draw_button(center[0], center[1] + 10 * self.scale, "Start", 120, 50, (0, 0))
def draw_button(self, x, y, text, width, height, coords):
if self.button_cursor[0] == coords[0] and self.button_cursor[1] == coords[1]:
color = (0, 0, 255)
self.draw_rectangle(x, y, width, height, "button", outline8u=color)
self.draw_text(text, self.fonts[20], (x + 10, y + 10), (0,0,0))
def get_view_center(self):
return self.w_offset + self.width // 2, self.h_offset + self.height // 2
View File
+15 -7
View File
@@ -7,6 +7,7 @@ from engine import maze, sdl2 as engine, controls
import os
import datetime
import subprocess
import json
class MiceMaze(controls.KeyBindings):
def __init__(self, maze_file):
@@ -27,13 +28,19 @@ class MiceMaze(controls.KeyBindings):
self.scrolling_direction = None
self.pause = False
self.game_end = (False, None)
self.dialog = "start_menu"
self.scrolling = False
self.sounds = {}
self.start_game()
self.background_texture = None
keybindings_file, = "keybinding_game.json",
with open(os.path.join("conf", keybindings_file)) as f:
self.keybindings = json.load(f)
def start_game(self):
for _ in range(5):
self.new_rat()
self.background_texture = None
def count_rats(self):
count = 0
for unit in self.units.values():
@@ -78,9 +85,9 @@ class MiceMaze(controls.KeyBindings):
def game_over(self):
if self.game_end[0]:
if not self.game_end[1]:
self.engine.win_screen("Game Over: Mice are too many!", image=self.assets["BMP_WEWIN"])
self.engine.dialog("Game Over: Mice are too many!", image=self.assets["BMP_WEWIN"])
else:
self.engine.win_screen(f"You Win! Points: {self.points}", image=self.assets["BMP_WEWIN"], scores=self.read_score())
self.engine.dialog(f"You Win! Points: {self.points}", image=self.assets["BMP_WEWIN"], scores=self.read_score())
return True
@@ -106,7 +113,9 @@ class MiceMaze(controls.KeyBindings):
def update_maze(self):
if self.pause:
self.engine.pause_screen("Paused")
if self.dialog != "start_menu":
self.engine.dialog("Pause")
self.engine.start_dialog(image=self.assets["BMP_WEWIN"])
return
if self.game_over():
return
@@ -128,7 +137,6 @@ class MiceMaze(controls.KeyBindings):
def run(self):
self.draw_maze()
self.engine.mainloop(update=self.update_maze, bg_update=self.draw_maze)
def scroll_cursor(self, x=0, y=0):
Executable → Regular
BIN
View File
Binary file not shown.
Executable → Regular
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -1
View File
@@ -103,7 +103,9 @@ class Rat(Unit):
self.game.spawn_unit(Point, unit.position_before, value=score)
def draw(self):
start_perf = self.game.engine.get_perf_counter()
direction = self.calculate_rat_direction()
sex = self.sex if self.age > AGE_THRESHOLD else "BABY"
image = self.game.rat_assets[sex][direction]
image_size = self.game.engine.get_image_size(image)
@@ -117,7 +119,6 @@ class Rat(Unit):
x_pos = self.position_before[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x
y_pos = self.position_before[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y
self.game.engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")
self.bbox = (x_pos, y_pos, x_pos + image_size[0], y_pos + image_size[1])
#self.game.engine.draw_rectangle(self.bbox[0], self.bbox[1], self.bbox[2] - self.bbox[0], self.bbox[3] - self.bbox[1], "unit")
+8 -11
View File
@@ -1,15 +1,12 @@
<game>
<path>./dRally.sh</path>
<name>Death Rally</name>
<desc>Death Rally is a strategic top-down racing game where players start with a modest budget and car, competing across 19 tracks in races against increasingly challenging opponents to earn money for upgrades. With choices of six car models and enhancements in engi>
In addition to race earnings, players can score bonuses for achievements like wiping out all competition, completing races unscathed, or fulfilling sponsor missions. Bonuses vary based on the chosen car, with the ultimate goal being to top the championship table and defeat the Adve>
<image>./drally/cover.png</image>
<releasedate>19960101T000000</releasedate>
<developer>Remedy Entertainment Ltd.</developer>
<publisher>Apogee Software</publisher>
<genre>Simulation-Race 3rd Pers. view-Race, Driving</genre>
<players>1-4</players>
<path>/roms/tools/mice/rats</path>
<name>Mice!</name>
<desc>Mice! is a strategic game where players must kill rats with bombs before they reproduce and become too numerous. The game is a clone of the classic game Rats! for Windows 95. <image>./drally/cover.png</image>
<releasedate>20241225T000000</releasedate>
<developer>Matteo Benedetto</developer>
<publisher>Check Mate Corp.</publisher>
<genre>Casual</genre>
<players>1</players>
<playcount>1</playcount>
<lastplayed>20240915T212155</lastplayed>
</game>