From 3ccffdca7d1ae394f268994e840ce5aff0dd5d0d Mon Sep 17 00:00:00 2001 From: Matteo Benedetto Date: Sun, 15 Dec 2024 18:56:51 +0100 Subject: [PATCH] =?UTF-8?q?Modifica=20il=20sistema=20di=20rendering=20SDL?= =?UTF-8?q?=20e=20migliora=20la=20gestione=20delle=20unit=C3=A0=20nel=20gi?= =?UTF-8?q?oco?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine/sdl2.py | 6 ++-- rats.py | 24 +++++++++++-- sdl2-tk-demo.py | 50 ++++++++++++++++++++++++++ units/__pycache__/rat.cpython-313.pyc | Bin 9493 -> 9945 bytes units/rat.py | 43 +++++++++++----------- 5 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 sdl2-tk-demo.py diff --git a/engine/sdl2.py b/engine/sdl2.py index 497ed58..0e0286a 100644 --- a/engine/sdl2.py +++ b/engine/sdl2.py @@ -12,10 +12,10 @@ class GameWindow: self.width = width * cell_size self.height = height * cell_size self.delay = 50 - sdl2.ext.init() + sdl2.ext.init(sdl2.SDL_INIT_VIDEO) self.window = sdl2.ext.Window(title=title, size=(self.width, self.height)) self.window.show() - self.renderer = sdl2.ext.Renderer(self.window, flags=sdl2.SDL_RENDERER_ACCELERATED) + self.renderer = sdl2.ext.Renderer(self.window, flags=sdl2.SDL_RENDERER_PRESENTVSYNC) self.factory = sdl2.ext.SpriteFactory(renderer=self.renderer) self.fonts = self.generate_fonts("assets/AmaticSC-Regular.ttf") self.running = True @@ -84,4 +84,4 @@ class GameWindow: self.running = False # Disegna qui gli sprite self.renderer.present() - time.sleep(self.delay / 1000) + #time.sleep(self.delay / 1000) diff --git a/rats.py b/rats.py index da9969d..3fb5337 100644 --- a/rats.py +++ b/rats.py @@ -1,3 +1,5 @@ +import cProfile +import pstats import random from units import rat import uuid @@ -7,11 +9,13 @@ from engine import maze, sdl2 as engine class MiceMaze: def __init__(self, maze_file): self.map = maze.Map(maze_file) - self.audio = True + self.audio = False self.cell_size = 60 self.engine = engine.GameWindow(self.map.width, self.map.height, self.cell_size, "Mice!", key_callback=self.key_pressed) self.graphics_load() self.units = {} + self.unit_positions = {} + self.unit_positions_before = {} for _ in range(5): self.new_rat() @@ -40,6 +44,11 @@ class MiceMaze: def update_maze(self): self.engine.delete_tag("unit") + self.unit_positions.clear() + self.unit_positions_before.clear() + for unit in self.units.values(): + self.unit_positions.setdefault(unit.position, []).append(unit) + self.unit_positions_before.setdefault(unit.position_before, []).append(unit) for unit in self.units.copy().values(): unit.move() unit.collisions() @@ -62,6 +71,10 @@ class MiceMaze: self.units[random.choice(list(self.units.keys()))].die() elif event.keysym == "m": self.audio = not self.audio + elif event.keysym == "s": + profiler.disable() + stats = pstats.Stats(profiler).sort_stats('cumtime') + stats.print_stats() def play_sound(self, sound_file): if self.audio: @@ -75,5 +88,10 @@ class MiceMaze: self.rat_assets[sex] = {} for direction in ["UP", "DOWN", "LEFT", "RIGHT"]: self.rat_assets[sex][direction] = self.engine.load_image(f"Rat/BMP_{sex}_{direction}.png", transparent_color=(128, 128, 128)) -solver = MiceMaze('maze.json') -solver.run() +if __name__ == "__main__": + profiler = cProfile.Profile() + profiler.enable() + + solver = MiceMaze('maze.json') + solver.run() + diff --git a/sdl2-tk-demo.py b/sdl2-tk-demo.py new file mode 100644 index 0000000..c16f5ad --- /dev/null +++ b/sdl2-tk-demo.py @@ -0,0 +1,50 @@ +from sdl2 import * +import tkinter as tk +from tkinter import * +import random, ctypes + +def draw(): + global renderer + x1 = ctypes.c_int(random.randrange(0, 600)) + y1 = ctypes.c_int(random.randrange(0, 500)) + x2 = ctypes.c_int(random.randrange(0, 600)) + y2 = ctypes.c_int(random.randrange(0, 500)) + r = ctypes.c_ubyte(random.randrange(0, 255)) + g = ctypes.c_ubyte(random.randrange(0, 255)) + b = ctypes.c_ubyte(random.randrange(0, 255)) + SDL_SetRenderDrawColor(renderer, r, g, b, ctypes.c_ubyte(255)) + SDL_RenderDrawLine(renderer, x1, y1, x2, y2) + +def sdl_update(): + global window, event, renderer + SDL_RenderPresent(renderer); + if SDL_PollEvent(ctypes.byref(event)) != 0: + if event.type == SDL_QUIT: + SDL_DestroyRenderer(renderer) + SDL_DestroyWindow(window) + SDL_Quit() + +# tkinter stuff # +root = tk.Tk() +embed = tk.Frame(root, width = 500, height = 500) #creates embed frame for pygame window +embed.grid(columnspan = (600), rowspan = 500) # Adds grid +embed.pack(side = LEFT) #packs window to the left +buttonwin = tk.Frame(root, width = 75, height = 500) +buttonwin.pack(side = LEFT) +button1 = Button(buttonwin,text = 'Draw', command=draw) +button1.pack(side=LEFT) +root.update() +################################# +# SDL window stuff # +SDL_Init(SDL_INIT_VIDEO) +window = SDL_CreateWindowFrom(embed.winfo_id()) +renderer = SDL_CreateRenderer(window, -1, 0) +SDL_SetRenderDrawColor(renderer, ctypes.c_ubyte(255), ctypes.c_ubyte(255), + ctypes.c_ubyte(255), ctypes.c_ubyte(255)) +SDL_RenderClear(renderer) +event = SDL_Event() +draw() + +while True: + sdl_update() + root.update() \ No newline at end of file diff --git a/units/__pycache__/rat.cpython-313.pyc b/units/__pycache__/rat.cpython-313.pyc index ba90b4b2c7d05411352efd9efd868bcfd815e149..d202cc54113a7ed59ec30117bc74f86f4330329f 100644 GIT binary patch delta 3076 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 adO;8#k%~`=^HXAfMC#ZN>N^ZF=>G{^{h(X` diff --git a/units/rat.py b/units/rat.py index 67c1e4a..8729553 100644 --- a/units/rat.py +++ b/units/rat.py @@ -1,7 +1,6 @@ from .unit import Unit import random import uuid -from engine.tkinter import GameWindow # Costanti AGE_THRESHOLD = 200 @@ -55,16 +54,14 @@ class Rat(Unit): self.age += 1 if self.age == AGE_THRESHOLD: self.speed *= SPEED_REDUCTION - if hasattr(self, "pregnant"): - if self.pregnant: - self.procreate() + if getattr(self, "pregnant", False): + self.procreate() if self.stop: self.stop -= 1 return if self.partial_move < 1: - self.partial_move += self.speed - self.partial_move = round(self.partial_move, 2) - if self.partial_move == 1: + self.partial_move = round(self.partial_move + self.speed, 2) + if self.partial_move >= 1: self.partial_move = 0 self.position = self.find_next_position() self.direction = self.calculate_rat_direction() @@ -72,27 +69,29 @@ class Rat(Unit): def collisions(self): if self.age < AGE_THRESHOLD: return - units = self.game.units.copy().values() + units = [] + units.extend(self.game.unit_positions.get(self.position, [])) + units.extend(self.game.unit_positions.get(self.position_before, [])) + units.extend(self.game.unit_positions_before.get(self.position, [])) + units.extend(self.game.unit_positions_before.get(self.position_before, [])) + for unit in units: - if unit.id == self.id: - continue - if unit.age < AGE_THRESHOLD: + if unit.id == self.id or unit.age < AGE_THRESHOLD: continue x1, y1, x2, y2 = self.bbox ox1, oy1, ox2, oy2 = unit.bbox # Verifica se c'รจ collisione con una tolleranza di sovrapposizione - if not (x1 < ox2 - OVERLAP_TOLERANCE and - x2 > ox1 + OVERLAP_TOLERANCE and - y1 < oy2 - OVERLAP_TOLERANCE and - y2 > oy1 + OVERLAP_TOLERANCE): - continue - if self.id in self.game.units and unit.id in self.game.units: - if self.sex == unit.sex and self.fight: - self.die(unit) - elif self.sex != unit.sex: - if "fuck" in dir(self): - self.fuck(unit) + if (x1 < ox2 - OVERLAP_TOLERANCE and + x2 > ox1 + OVERLAP_TOLERANCE and + y1 < oy2 - OVERLAP_TOLERANCE and + y2 > oy1 + OVERLAP_TOLERANCE): + if self.id in self.game.units and unit.id in self.game.units: + if self.sex == unit.sex and self.fight: + self.die(unit) + elif self.sex != unit.sex: + if "fuck" in dir(self): + self.fuck(unit) def die(self, unit=None): if not unit: