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
RESOLUTION=1920x1080
+3 -1
View File
@@ -13,7 +13,7 @@ class KeyBindings:
self.new_rat()
elif key == "D":
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":
self.audio = not self.audio
elif key == "F":
@@ -32,6 +32,8 @@ class KeyBindings:
self.spawn_bomb(self.pointer)
elif key == "UpRelease" or key == "DownRelease" or key == "LeftRelease" or key == "RightRelease":
self.stop_scrolling()
elif key == "P":
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
+23 -5
View File
@@ -1,6 +1,8 @@
import os
import sdl2
import sdl2.ext
from sdl2.ext.compat import byteify
from PIL import Image
class GameWindow:
@@ -9,8 +11,8 @@ class GameWindow:
self.cell_size = cell_size
self.width = width * cell_size
self.height = height * cell_size
self.actual_screen_size = (640, 480)
if self.width > self.actual_screen_size[0] or self.height > self.actual_screen_size[1]:
self.actual_screen_size = os.environ.get("RESOLUTION", "640x480").split("x")
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
else:
self.target_size = (self.width, self.height)
@@ -22,6 +24,8 @@ class GameWindow:
self.max_h_offset = self.target_size[1] - self.height
print(f"Screen size: {self.width}x{self.height}")
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.delay = 30
self.load_joystick()
@@ -63,7 +67,7 @@ class GameWindow:
def draw_text(self, text, font, position, color):
sprite = self.factory.from_text(text, color=color, fontmanager=font)
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:
sprite.position = position
self.renderer.copy(sprite, dstrect=sprite.position)
@@ -75,8 +79,6 @@ class GameWindow:
self.renderer.copy(sprite, dstrect=sprite.position)
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
if filling:
self.renderer.fill((x, y, width, height), sdl2.ext.Color(*filling))
@@ -92,6 +94,21 @@ class GameWindow:
def delete_tag(self, tag):
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):
return image.size
@@ -174,6 +191,7 @@ class GameWindow:
self.h_offset = y
def play_sound(self, sound_file):
return
sample = sdl2.sdlmixer.Mix_LoadWAV(byteify(sound_file, "utf-8"))
if sample is None:
+49 -8
View File
@@ -1,12 +1,12 @@
#!/usr/bin/python3
import cProfile
import pstats
import random
from units import rat, bomb
import uuid
import subprocess
from engine import maze, sdl2 as engine, controls
import os
import datetime
import subprocess
class MiceMaze(controls.KeyBindings):
def __init__(self, maze_file):
@@ -23,7 +23,10 @@ class MiceMaze(controls.KeyBindings):
self.unit_positions = {}
self.unit_positions_before = {}
self.scrolling_direction = None
self.pause = False
self.game_end = (False, None)
self.scrolling = False
self.sounds = {}
for _ in range(5):
self.new_rat()
@@ -55,8 +58,41 @@ class MiceMaze(controls.KeyBindings):
variant = x*y % 4
tile = self.grasses[variant] if cell else self.tunnel
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):
if self.pause:
self.engine.pause_screen("Paused")
return
if self.game_over():
return
self.engine.delete_tag("unit")
self.engine.delete_tag("effect")
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)
def play_sound(self, sound_file):
def play_sound(self, sound_file,tag="main"):
if self.audio:
subprocess.Popen(["aplay", f"sound/{sound_file}"])
#self.engine.play_sound(f"sound/{sound_file}")
if len(self.sounds) > 5:
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):
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)
if __name__ == "__main__":
profiler = cProfile.Profile()
profiler.enable()
solver = MiceMaze('maze.json')
solver.run()
-1
View File
@@ -1,2 +1 @@
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:
self.die()
def die(self, unit=None):
def die(self, unit=None, score=None):
score = 10
print("BOOM")
if not unit:
unit = self
@@ -68,11 +69,15 @@ class Timer(Bomb):
for victim in self.game.unit_positions.get((x, y), []):
if victim.id in self.game.units:
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), []):
if victim.id in self.game.units:
if victim.partial_move < 0.5:
victim.die()
victim.die(score=score)
if score < 160:
score *= 2
else:
break
if direction == "N":
+1 -1
View File
@@ -30,7 +30,7 @@ class Point(Unit):
def collisions(self):
pass
def die(self, unit=None):
def die(self, unit=None, score=None):
if not unit:
unit = self
self.game.units.pop(unit.id)
+2 -2
View File
@@ -96,11 +96,11 @@ class Rat(Unit):
if "fuck" in dir(self):
self.fuck(unit)
def die(self, unit=None):
def die(self, unit=None, score=10):
if not unit:
unit = self
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):
direction = self.calculate_rat_direction()