Aggiungi supporto per la risoluzione personalizzata e gestione della pausa nel gioco

This commit is contained in:
2024-12-23 00:59:48 +01:00
parent 42e2f4aa16
commit 97038023d5
10 changed files with 93 additions and 24 deletions
+1
View File
@@ -1 +1,2 @@
SDL_VIDEODRIVER=x11 SDL_VIDEODRIVER=x11
RESOLUTION=1920x1080
+3 -1
View File
@@ -13,7 +13,7 @@ class KeyBindings:
self.new_rat() self.new_rat()
elif key == "D": elif key == "D":
if self.units: if self.units:
self.units[random.choice(list(self.units.keys()))].die() self.units[random.choice(list(self.units.keys()))].die(score=5)
elif key == "M": elif key == "M":
self.audio = not self.audio self.audio = not self.audio
elif key == "F": elif key == "F":
@@ -32,6 +32,8 @@ class KeyBindings:
self.spawn_bomb(self.pointer) self.spawn_bomb(self.pointer)
elif key == "UpRelease" or key == "DownRelease" or key == "LeftRelease" or key == "RightRelease": elif key == "UpRelease" or key == "DownRelease" or key == "LeftRelease" or key == "RightRelease":
self.stop_scrolling() self.stop_scrolling()
elif key == "P":
self.pause = not self.pause
# elif key == "mouse": # elif key == "mouse":
# adjusted_coords = (coords[0]//self.cell_size*2, coords[1]//self.cell_size*2) # adjusted_coords = (coords[0]//self.cell_size*2, coords[1]//self.cell_size*2)
# self.pointer = adjusted_coords # self.pointer = adjusted_coords
+23 -5
View File
@@ -1,6 +1,8 @@
import os import os
import sdl2 import sdl2
import sdl2.ext import sdl2.ext
from sdl2.ext.compat import byteify
from PIL import Image from PIL import Image
class GameWindow: class GameWindow:
@@ -9,8 +11,8 @@ class GameWindow:
self.cell_size = cell_size self.cell_size = cell_size
self.width = width * cell_size self.width = width * cell_size
self.height = height * cell_size self.height = height * cell_size
self.actual_screen_size = (640, 480) self.actual_screen_size = os.environ.get("RESOLUTION", "640x480").split("x")
if self.width > self.actual_screen_size[0] or self.height > self.actual_screen_size[1]: if self.width > int(self.actual_screen_size[0]) or self.height > int(self.actual_screen_size[1]):
self.target_size = self.actual_screen_size self.target_size = self.actual_screen_size
else: else:
self.target_size = (self.width, self.height) self.target_size = (self.width, self.height)
@@ -22,6 +24,8 @@ class GameWindow:
self.max_h_offset = self.target_size[1] - self.height self.max_h_offset = self.target_size[1] - self.height
print(f"Screen size: {self.width}x{self.height}") print(f"Screen size: {self.width}x{self.height}")
sdl2.ext.init(joystick=True) sdl2.ext.init(joystick=True)
sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO)
self.window = sdl2.ext.Window(title=title, size=self.target_size,)# flags=sdl2.SDL_WINDOW_FULLSCREEN) self.window = sdl2.ext.Window(title=title, size=self.target_size,)# flags=sdl2.SDL_WINDOW_FULLSCREEN)
self.delay = 30 self.delay = 30
self.load_joystick() self.load_joystick()
@@ -63,7 +67,7 @@ class GameWindow:
def draw_text(self, text, font, position, color): def draw_text(self, text, font, position, color):
sprite = self.factory.from_text(text, color=color, fontmanager=font) sprite = self.factory.from_text(text, color=color, fontmanager=font)
if position == "center": if position == "center":
sprite.position = (self.size[0] // 2 - sprite.size[0] // 2, self.size[1] // 2 - sprite.size[1] // 2) sprite.position = (self.target_size[0] // 2 - sprite.size[0] // 2, self.target_size[1] // 2 - sprite.size[1] // 2)
else: else:
sprite.position = position sprite.position = position
self.renderer.copy(sprite, dstrect=sprite.position) self.renderer.copy(sprite, dstrect=sprite.position)
@@ -75,8 +79,6 @@ class GameWindow:
self.renderer.copy(sprite, dstrect=sprite.position) self.renderer.copy(sprite, dstrect=sprite.position)
def draw_rectangle(self, x, y, width, height, tag, outline="red", filling=None): def draw_rectangle(self, x, y, width, height, tag, outline="red", filling=None):
if not self.is_in_visible_area(x, y):
return
x, y = x + self.w_offset, y + self.h_offset x, y = x + self.w_offset, y + self.h_offset
if filling: if filling:
self.renderer.fill((x, y, width, height), sdl2.ext.Color(*filling)) self.renderer.fill((x, y, width, height), sdl2.ext.Color(*filling))
@@ -92,6 +94,21 @@ class GameWindow:
def delete_tag(self, tag): def delete_tag(self, tag):
pass pass
def win_screen(self, text, image=None):
self.draw_rectangle(50 - self.w_offset, 50 - self.h_offset,
self.target_size[0] - 100, self.target_size[1] - 100, "win", filling=(255, 255, 255))
self.draw_text(text, self.fonts[50], "center", sdl2.ext.Color(0, 0, 0))
if image:
image_size = self.get_image_size(image)
self.draw_image(self.target_size[0] // 2 - image_size[0] // 2,
self.target_size[1] // 2 - image_size[1] // 2-150, image, "win")
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[50], "center", sdl2.ext.Color(0, 0, 0))
def get_image_size(self, image): def get_image_size(self, image):
return image.size return image.size
@@ -174,6 +191,7 @@ class GameWindow:
self.h_offset = y self.h_offset = y
def play_sound(self, sound_file): def play_sound(self, sound_file):
return return
sample = sdl2.sdlmixer.Mix_LoadWAV(byteify(sound_file, "utf-8")) sample = sdl2.sdlmixer.Mix_LoadWAV(byteify(sound_file, "utf-8"))
if sample is None: if sample is None:
+49 -8
View File
@@ -1,12 +1,12 @@
#!/usr/bin/python3 #!/usr/bin/python3
import cProfile
import pstats
import random import random
from units import rat, bomb from units import rat, bomb
import uuid import uuid
import subprocess
from engine import maze, sdl2 as engine, controls from engine import maze, sdl2 as engine, controls
import os import os
import datetime
import subprocess
class MiceMaze(controls.KeyBindings): class MiceMaze(controls.KeyBindings):
def __init__(self, maze_file): def __init__(self, maze_file):
@@ -23,7 +23,10 @@ class MiceMaze(controls.KeyBindings):
self.unit_positions = {} self.unit_positions = {}
self.unit_positions_before = {} self.unit_positions_before = {}
self.scrolling_direction = None self.scrolling_direction = None
self.pause = False
self.game_end = (False, None)
self.scrolling = False self.scrolling = False
self.sounds = {}
for _ in range(5): for _ in range(5):
self.new_rat() self.new_rat()
@@ -55,8 +58,41 @@ class MiceMaze(controls.KeyBindings):
variant = x*y % 4 variant = x*y % 4
tile = self.grasses[variant] if cell else self.tunnel tile = self.grasses[variant] if cell else self.tunnel
self.engine.draw_image(x * self.cell_size, y * self.cell_size, tile, tag="maze") self.engine.draw_image(x * self.cell_size, y * self.cell_size, tile, tag="maze")
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"])
else:
self.engine.win_screen(f"You Win! Points: {self.points}", image=self.assets["BMP_WEWIN"])
return True
if len(self.units) >= 150:
self.stop_sound()
self.play_sound("WEWIN.WAV")
self.game_end = (True, False)
return True
if not len(self.units):
self.stop_sound()
self.play_sound("VICTORY.WAV")
self.game_end = (True, True)
self.save_score()
return True
def save_score(self):
with open("scores.txt", "a") as f:
f.write(f"{datetime.datetime.now()} - {self.points}\n")
def read_score(self):
with open("scores.txt") as f:
return f.read().splitlines()
def update_maze(self): def update_maze(self):
if self.pause:
self.engine.pause_screen("Paused")
return
if self.game_over():
return
self.engine.delete_tag("unit") self.engine.delete_tag("unit")
self.engine.delete_tag("effect") self.engine.delete_tag("effect")
self.engine.draw_pointer(self.pointer[0] * self.cell_size, self.pointer[1] * self.cell_size) self.engine.draw_pointer(self.pointer[0] * self.cell_size, self.pointer[1] * self.cell_size)
@@ -87,10 +123,17 @@ class MiceMaze(controls.KeyBindings):
) )
self.engine.scroll_view(self.pointer) self.engine.scroll_view(self.pointer)
def play_sound(self, sound_file): def play_sound(self, sound_file,tag="main"):
if self.audio: if self.audio:
subprocess.Popen(["aplay", f"sound/{sound_file}"]) if len(self.sounds) > 5:
#self.engine.play_sound(f"sound/{sound_file}") self.sounds.pop(next(iter(self.sounds))).kill()
self.sounds[f"{tag}_{random.random()}"] = subprocess.Popen(["aplay", f"sound/{sound_file}"])
def stop_sound(self, tag=None):
for key, value in self.sounds.copy().items():
if tag is None or tag in key:
value.kill()
del self.sounds[key]
def graphics_load(self): def graphics_load(self):
self.tunnel = self.engine.load_image("Rat/BMP_TUNNEL.png") self.tunnel = self.engine.load_image("Rat/BMP_TUNNEL.png")
@@ -131,8 +174,6 @@ class MiceMaze(controls.KeyBindings):
self.engine.new_cycle(100, self.scroll) self.engine.new_cycle(100, self.scroll)
if __name__ == "__main__": if __name__ == "__main__":
profiler = cProfile.Profile()
profiler.enable()
solver = MiceMaze('maze.json') solver = MiceMaze('maze.json')
solver.run() solver.run()
-1
View File
@@ -1,2 +1 @@
pysdl2 pysdl2
pysdl2-dll
+3
View File
@@ -0,0 +1,3 @@
2024-12-23 00:31:05.911787 - 25
2024-12-23 00:34:28.819938 - 50
2024-12-23 00:56:30.216347 - 25
Binary file not shown.
+8 -3
View File
@@ -53,7 +53,8 @@ class Timer(Bomb):
if self.age == AGE_THRESHOLD: if self.age == AGE_THRESHOLD:
self.die() self.die()
def die(self, unit=None): def die(self, unit=None, score=None):
score = 10
print("BOOM") print("BOOM")
if not unit: if not unit:
unit = self unit = self
@@ -68,11 +69,15 @@ class Timer(Bomb):
for victim in self.game.unit_positions.get((x, y), []): for victim in self.game.unit_positions.get((x, y), []):
if victim.id in self.game.units: if victim.id in self.game.units:
if victim.partial_move >= 0.5: if victim.partial_move >= 0.5:
victim.die() victim.die(score=score)
if score < 160:
score *= 2
for victim in self.game.unit_positions_before.get((x, y), []): for victim in self.game.unit_positions_before.get((x, y), []):
if victim.id in self.game.units: if victim.id in self.game.units:
if victim.partial_move < 0.5: if victim.partial_move < 0.5:
victim.die() victim.die(score=score)
if score < 160:
score *= 2
else: else:
break break
if direction == "N": if direction == "N":
+1 -1
View File
@@ -30,7 +30,7 @@ class Point(Unit):
def collisions(self): def collisions(self):
pass pass
def die(self, unit=None): def die(self, unit=None, score=None):
if not unit: if not unit:
unit = self unit = self
self.game.units.pop(unit.id) self.game.units.pop(unit.id)
+2 -2
View File
@@ -96,11 +96,11 @@ class Rat(Unit):
if "fuck" in dir(self): if "fuck" in dir(self):
self.fuck(unit) self.fuck(unit)
def die(self, unit=None): def die(self, unit=None, score=10):
if not unit: if not unit:
unit = self unit = self
self.game.units.pop(unit.id) self.game.units.pop(unit.id)
self.game.spawn_unit(Point, unit.position_before) self.game.spawn_unit(Point, unit.position_before, value=score)
def draw(self): def draw(self):
direction = self.calculate_rat_direction() direction = self.calculate_rat_direction()