diff --git a/src/engine/engine.py b/src/engine/engine.py index ce18718..0b86865 100644 --- a/src/engine/engine.py +++ b/src/engine/engine.py @@ -36,7 +36,7 @@ class Engine: self.boss_fight_manager = BossFightManager(self) self.event_sheduler = EventSheduler(self) self.dialogs_manager = DialogsManager(self.event_handler) - self.menu_manager = MenuManager() + self.menu_manager = MenuManager(self) def loop(self): """Fonction à lancer au début du programme et qui va lancer les updates dans une boucle. diff --git a/src/engine/event_handler.py b/src/engine/event_handler.py index c4c976d..242f2b8 100644 --- a/src/engine/event_handler.py +++ b/src/engine/event_handler.py @@ -14,6 +14,7 @@ class EventHandler: self.engine = core self.key_pressed = [] self.buttons_area = [] + self.hovered_area = [] @staticmethod def get_click_collision(rect: tuple[float | int, float | int, float | int, float | int], point: tuple[int, int], @@ -37,11 +38,12 @@ class EventHandler: def register_button_area(self, rect: tuple[float | int, float | int, float | int, float | int], callback: FunctionType | classmethod | staticmethod, name: str, - is_window_relative: int = -1): + is_window_relative: int = -1, + hover_callback: FunctionType | classmethod | staticmethod = None): """Enregistre une zone comme bouton. La fonction donnée sera donc executé lorsque la zone sur la fenêtre sera cliqué. is_window_relative doit être 0 pour que le rect soit multipliée par la largeur de la fenêtre et 1 pour qu'elle soit multipliée par la hauteur""" - self.buttons_area.append((rect, callback, is_window_relative, name)) + self.buttons_area.append((rect, callback, is_window_relative, name, hover_callback)) def remove_button_area(self, name: str): """Supprime les boutons aux noms donnés.""" @@ -72,6 +74,10 @@ class EventHandler: for area in self.buttons_area: if self.get_click_collision(area[0], e.pos, area[2]): area[1]() + elif e.type == MOUSEMOTION: + for area in self.buttons_area: + if area[4] is not None and self.get_click_collision(area[0], e.pos, area[2]): + area[4]() if self.engine.entity_manager.player_entity_name: if K_RIGHT in self.key_pressed: diff --git a/src/engine/menu_manager.py b/src/engine/menu_manager.py index 27929fa..44dcb1f 100644 --- a/src/engine/menu_manager.py +++ b/src/engine/menu_manager.py @@ -1,9 +1,9 @@ -import threading -import tkinter from types import FunctionType import pygame +import src.engine.engine + class Widget: """Classe parente des widgets de menu.""" @@ -28,7 +28,8 @@ class Button(Widget): """Un widget de bouton.""" def __init__(self, x: int | float, y: int | float, text: str, size: int | float, color: tuple[int, int, int], callback: FunctionType | classmethod | staticmethod, base_image: pygame.Surface, - hover_image: pygame.Surface, centered: bool = False, is_window_relative: int = -1): + hover_image: pygame.Surface, centered: bool = False, is_window_relative: int = -1, + area_name: str = "menu_button"): super().__init__(x, y, is_window_relative) self.text = text self.size = size @@ -37,6 +38,11 @@ class Button(Widget): self.base_image = base_image self.hover_image = hover_image self.centered = centered + self.area_name = area_name + self.hovered = False + + def set_hover_state(self, state: bool): + self.hovered = state class Menu: @@ -52,14 +58,29 @@ class Menu: class MenuManager: """Classe qui gère les menus.""" - def __init__(self): + def __init__(self, engine: 'src.engine.engine.Engine'): self.menus = {} self.active_menu: Menu | None = None + self.engine = engine def register_menu(self, menu: Menu, name: str): """Ajoute le menu donné au manager de menu avec le nom donné.""" self.menus[name] = menu + # On itère dans tous les bouttons pour leur ajouter une interaction + for btn in menu.widgets: + if isinstance(btn, Button): + width = btn.base_image.get_width()/self.engine.renderer.window_size[0] + height = btn.base_image.get_height()/self.engine.renderer.window_size[1] + area_x = btn.x + area_y = btn.y + if btn.centered: + area_x -= width/2 + area_y -= height/2 + self.engine.event_handler.register_button_area((area_x, area_y, width, height), btn.callback, btn.area_name, + btn.is_window_relative, lambda: print("hover")) + print(btn.is_window_relative) + def show(self, name: str): """Affiche le menu au nom donné.""" self.active_menu = self.menus[name] diff --git a/src/engine/renderer.py b/src/engine/renderer.py index 7d13849..894cafb 100644 --- a/src/engine/renderer.py +++ b/src/engine/renderer.py @@ -191,7 +191,6 @@ class Renderer: else: self.window.blit(rendered_text, (x, y)) elif isinstance(widget, Button): - print("a") # On multiplie la taille du texte si besoin if widget.is_window_relative == 0: size = widget.size*window_size[0] @@ -204,14 +203,24 @@ class Renderer: text_font = font.SysFont("Arial", round(size)) - # On affiche l'image du boutton - self.window.blit(widget.base_image, (x-widget.base_image.get_width()//2, - y-widget.base_image.get_height()//2)) - rendered_text = text_font.render(widget.text, True, widget.color) - self.window.blit(rendered_text, (x-rendered_text.get_width()//2, - y-rendered_text.get_height()//2)) + btn_image = widget.base_image + btn_image = transform.scale(btn_image, (btn_image.get_width()*window_size[0]/self.window_size[0], + btn_image.get_height()*window_size[0]/self.window_size[0])) + + # On affiche l'image du boutton + if widget.centered: + self.window.blit(btn_image, (x-btn_image.get_width()//2, + y-btn_image.get_height()//2)) + + self.window.blit(rendered_text, (x-rendered_text.get_width()//2, + y-rendered_text.get_height()//2)) + + else: + self.window.blit(btn_image, (x, y)) + + self.window.blit(rendered_text, (x, y)) def render_dialogs_box(self): """Rend la boite de dialogue lorsqu'un dialogue est lancé.""" diff --git a/src/main.py b/src/main.py index ec16d23..d505fbb 100644 --- a/src/main.py +++ b/src/main.py @@ -38,7 +38,7 @@ class Game(Engine): base_image = pygame.image.load("assets/textures/GUI/button_1.png").convert_alpha() - menu.add_widget(Button(0.5, 0.3, "boutton", 0.1, (0, 255, 0), lambda : print("play"), base_image, base_image, True, 2)) + menu.add_widget(Button(0.5, 0.3, "boutton", 0.1, (0, 255, 0), lambda : print("play"), base_image, base_image, True, 0)) self.menu_manager.register_menu(menu, "main") self.menu_manager.show("main")