From 879e6e8c0d39f50ce749ec0709f6ae88c2def2db Mon Sep 17 00:00:00 2001 From: Yannis300307 Date: Fri, 5 Jan 2024 19:57:24 +0100 Subject: [PATCH] =?UTF-8?q?D=C3=A9but=20de=20rendu=20de=20dialogues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/dialogs.json | 2 +- assets/textures/GUI/dialogs_box.png | Bin 0 -> 5711 bytes src/engine/dialogs_manager.py | 24 +++++++++++- src/engine/engine.py | 1 + src/engine/renderer.py | 57 ++++++++++++++++++++-------- src/main.py | 8 ++-- 6 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 assets/textures/GUI/dialogs_box.png diff --git a/assets/dialogs.json b/assets/dialogs.json index 4c15f5f..7d8409b 100644 --- a/assets/dialogs.json +++ b/assets/dialogs.json @@ -1,4 +1,4 @@ { - "test": ["test1", "test2", "test très long permettant de tester le retour à la ligne dans le renderer du jeu dans la fonction qui rend les dialogues et il faut éviter d'en faire des si long car ça pourrait dépacer en base de l'écran ! Bonne journée !"], + "test": ["test1111", "test2", "test très long permettant de tester le retour à la ligne dans le renderer du jeu dans la fonction qui rend les dialogues et il faut éviter d'en faire des si long car ça pourrait dépacer en base de l'écran ! Bonne journée !"], "test2": ["salut", "aurevoir"] } \ No newline at end of file diff --git a/assets/textures/GUI/dialogs_box.png b/assets/textures/GUI/dialogs_box.png new file mode 100644 index 0000000000000000000000000000000000000000..2e7b56a79847fcbbecf85610743c346a3431cab2 GIT binary patch literal 5711 zcmeHLi&GOv7+(-gP^mB(r3FKDC~7OHts_VwyhM>Asik7D0YWVn&5=h7hDbnSu`mo( ztl0VhiGm6h3RXBk0Xd68tvs}ZWH=szl=AXOB9LH%NrQLbpJ1nxow?cD@AvI~-|g65t0)TUU-48x}FX!M*_e znzdx+i-pFvrC{g2H~`-IZT2x+zV2fQ0L%Xh^!ME(io|*%hVu?no79Hzj7tZ(zB|qx zA9Oek+cb|}Ngwnj(SJA-e<_;ed)Jv0FQY74nCcvR%qCwbr-T&-(XVsA+Zx@{LUkd3 zT4i@8!$GD^=u!Aw$?i!pD3rIoYa>EdADn zIB@5-<^-xoL+A06`cPdUMuL|Z@$(S40}J^W+CRJ2#g{-&Kdb^t+p*oh zBtL%#$D&%%wU_I|#a~yqAi3tMpHL;Fr15YJOlS+yCeBbAD<;koanXB)h_!+RI2J~2 zf^?i7N7YJmf$rG^jng|byK9VPZ>X3u-2j(LQ+qx0=sir`^ivxgiE@fyiXp7OUmmCg zNf4&X48Q@&kClbOo5KCohaXK)9x)Y+j#BEJ55>w(^aQ-5fxDmn1nBo-1@oQAO!q`im4?y?wuf8y8rdIl%cNx)^|;(8U$a7WF|+B=RN{hZ5mzzi z*s9hHG&r+qWRi@y$y%Kq&Q@s`)W|Ch)g_Gpv0&rN~rJx#iFtEx_#eE4AYSOwp6ZM!2-QroU34L#Dsh5VX; zdClgLHoXc-NJ&(PSZK?D`*{bc#4Cg~x^c9;4Y!P(VWe={?mA|9e$cz2QwohG`f5U^ z$Vf_A-2t`e5U*avR@>sL=VaRyu^(;qio71f34$LVn3}ejl&dXpaA)O#SAMX)@^Aro zu!dhiH{V3G?0o>SU&yNgvC7A-C1yD6M@9&})fQ3so5XsquMgSmZCtkMI9Q6mS^JrW zGtJ$ryHTDEP4mOvk6`Ut#*s;=y3LRG4m1rt2ae3#O~KDX%akQFtu8sRWd6 zt_m8k#Ca6yNLqNwH;$teJ*f0yguEY&^>9(Q7H0g zJj$q%O?iRV&C@LF(mB~pPp&EKk(Mp+XRzC{Ig+JA8;&)i-sxTU66?&m!;3JsCt)X{cg<-kKTCnD6vEeCrgmfF_rIjkz0HyzFNXsl!504=1Wd$1_xH8NNGIk)Qq=;{qxIh6)C3*8mw^NqqbBux@S&zH9G+}TStLzgDWma zx?kpNE~Cy*`I`$tcWqcrfsloDY6xxvY4&95!ZFR~3d4l9!!>KDyMiBWsFmxJ#GJA+ z!t& ~J<&$@G67J(m+a;2y(**hR2gYCo^<-@jrF str: + def get_current_dialog_sentence(self, progressive=True) -> str: """Renvoie la phrase actuelle du dialogue.""" - return self.current_dialogs[self.current_dialog_id] + if progressive: + return self.current_dialogs[self.current_dialog_id][:self.current_dialogue_letter_id] + else: + return self.current_dialogs[self.current_dialog_id] def load_dialogs(self, file_path: str): """Charge les dialogues du jeu grave au fichier json donné.""" with open(file_path, "r", encoding="utf-8") as file: self.dialogs = json.loads(file.read()) + + def update(self, delta: float): + """Met à jour e gestionnaire de dialogues.""" + if self.reading_dialog: + self.letter_timer -= delta + + if self.letter_timer <= 0: + self.letter_timer = self.LETTER_WRITTING_DELAY + self.current_dialogue_letter_id += 1 + if self.current_dialogue_letter_id > len(self.current_dialogs[self.current_dialog_id]): + self.current_dialogue_letter_id -= 1 + + print(self.get_current_dialog_sentence()) \ No newline at end of file diff --git a/src/engine/engine.py b/src/engine/engine.py index ca07190..69fb4b2 100644 --- a/src/engine/engine.py +++ b/src/engine/engine.py @@ -52,6 +52,7 @@ class Engine: self.renderer.update(0.016666666) self.event_handler.update() self.event_sheduler.update() + self.dialogs_manager.update(0.016666666) def stop(self): """Arrête le programme.""" diff --git a/src/engine/renderer.py b/src/engine/renderer.py index 0189465..2dad103 100644 --- a/src/engine/renderer.py +++ b/src/engine/renderer.py @@ -15,7 +15,8 @@ class Renderer: def __init__(self, core: 'engine.Engine'): self.engine = core self.window_type = RESIZABLE - self.window_size = (display.Info().current_w, display.Info().current_h) if self.window_type == FULLSCREEN else (600, 600) + self.window_size = (display.Info().current_w, display.Info().current_h) if self.window_type == FULLSCREEN else ( + 600, 600) self.window = display.set_mode(self.window_size, self.window_type) self.tiles = [] self.tile_size = 0 @@ -26,6 +27,9 @@ class Renderer: self.boss_fight_player_animations: dict[str: Anim] = {} self.boss_fight_GUI_container = None + # Boite de dialogue + self.dialogs_box = None + # Variables utilisées par le menu principal self.main_menu_assets: dict[str: Anim] = {} @@ -54,8 +58,8 @@ class Renderer: part_speed_y = - part_speed_y # On choisit sa position dans le rectangle - part_x = random.randint(x-w, x+w-part_size) - part_y = random.randint(y-h, y+h-part_size) + part_x = random.randint(x - w, x + w - part_size) + part_y = random.randint(y - h, y + h - part_size) # On choisit la durée de vie part_life_time = random.uniform(min_life_time, max_life_time) @@ -123,9 +127,28 @@ class Renderer: self.window.blit(font.SysFont("Arial", 20).render(f"Zoom: {self.engine.camera.zoom}", True, (255, 0, 0)), (0, 60)) + # Rendu présent dans tous les types de jeu + self.render_dialogs_box() + # Apres avoir tout rendu, on met à jour l'écran display.update() + def render_dialogs_box(self): + """Rend la boite de dialogue lorsqu'un dialogue est lancé.""" + + # Rend le conteneur des dialogues + if self.engine.dialogs_manager.reading_dialog: + resized_box = transform.scale(self.dialogs_box, + (display.get_window_size()[0], + self.dialogs_box.get_height() / self.dialogs_box.get_width() * + display.get_window_size()[0])) + self.window.blit(resized_box, (0, display.get_window_size()[1] - resized_box.get_height())) + + # Rend le texte + text_font = font.SysFont("Arial", display.get_window_size()[0]//20) + rendered_text = text_font.render(self.engine.dialogs_manager.get_current_dialog_sentence(), True, (0, 0, 0)) + self.window.blit(rendered_text, (display.get_window_size()[0]/30, display.get_window_size()[1] - resized_box.get_height()+display.get_window_size()[0]/30)) + def render_debug_area(self, rendered_surface: surface.Surface): """Rend les zones de collisions et de détections quand le mode DEBUG est activé.""" @@ -136,9 +159,9 @@ class Renderer: for area in self.engine.event_sheduler.area_callbacks: area_rect = area[0] draw.rect(rendered_surface, (200, 100, 0), - (math.floor(x_middle_offset+area_rect[0]-self.engine.camera.x), - math.floor(y_middle_offset+area_rect[1]-self.engine.camera.y), - math.floor(area_rect[2]), math.floor(area_rect[3])), width=1) + (math.floor(x_middle_offset + area_rect[0] - self.engine.camera.x), + math.floor(y_middle_offset + area_rect[1] - self.engine.camera.y), + math.floor(area_rect[2]), math.floor(area_rect[3])), width=1) def register_shadow(self, file_path: str, name: str): """Enregistre une image d'ombre utilisée pour le rendu des entités.""" @@ -184,8 +207,8 @@ class Renderer: frame = transform.scale(frame, (display.get_window_size()[0] / 5, display.get_window_size()[0] / 5)) # On colle le boss à droite de la fenêtre - self.window.blit(frame, (display.get_window_size()[0]-frame.get_width()-display.get_window_size()[0]/20, - display.get_window_size()[1]/4-frame.get_height()/2)) + self.window.blit(frame, (display.get_window_size()[0] - frame.get_width() - display.get_window_size()[0] / 20, + display.get_window_size()[1] / 4 - frame.get_height() / 2)) # On récupère l'image de l'animation du joueur player_animation = self.boss_fight_player_animations[self.engine.boss_fight_manager.current_player_animation] @@ -195,14 +218,17 @@ class Renderer: frame = transform.scale(frame, (display.get_window_size()[0] / 5, display.get_window_size()[0] / 5)) # On colle le joueur à gauche de la fenêtre - self.window.blit(frame, (display.get_window_size()[0]/20, display.get_window_size()[1]/4-frame.get_height()/2)) + self.window.blit(frame, + (display.get_window_size()[0] / 20, display.get_window_size()[1] / 4 - frame.get_height() / 2)) def render_boss_fight_gui(self): """Rend la barre d'action en bas de l'écran pendant le combat de boss.""" resized_container = transform.scale(self.boss_fight_GUI_container, - (display.get_window_size()[0], self.boss_fight_GUI_container.get_height()/self.boss_fight_GUI_container.get_width()*display.get_window_size()[0])) - self.window.blit(resized_container, (0, display.get_window_size()[1]-resized_container.get_height())) + (display.get_window_size()[0], + self.boss_fight_GUI_container.get_height() / self.boss_fight_GUI_container.get_width() * + display.get_window_size()[0])) + self.window.blit(resized_container, (0, display.get_window_size()[1] - resized_container.get_height())) def render_entities(self, rendered_surface: surface.Surface, gui_surface: surface.Surface, delta: float): """Rend toutes les entités.""" @@ -250,10 +276,11 @@ class Renderer: cooldown_value = entity.damage_cooldown / entity.default_damage_cooldown # On calcule où placer la barre de vei sur la surface des GUI - life_bar_dest = (math.floor((entity.x - self.engine.camera.x + x_middle_offset) * self.engine.camera.zoom - - life_bar_width / 2), - math.floor((entity.y - self.engine.camera.y + y_middle_offset - frame.get_height() / 2) * - self.engine.camera.zoom - life_bar_height - life_bar_y_offset)) + life_bar_dest = ( + math.floor((entity.x - self.engine.camera.x + x_middle_offset) * self.engine.camera.zoom - + life_bar_width / 2), + math.floor((entity.y - self.engine.camera.y + y_middle_offset - frame.get_height() / 2) * + self.engine.camera.zoom - life_bar_height - life_bar_y_offset)) # Contour de la barre de vie draw.rect(gui_surface, (20, 0, 0), (life_bar_dest[0] - life_bar_border, diff --git a/src/main.py b/src/main.py index eb753e1..90af9f2 100644 --- a/src/main.py +++ b/src/main.py @@ -22,7 +22,9 @@ class Game(Engine): self.game_state = GameState.NORMAL - self.event_sheduler.register_area((0, 20, 20, 20), None) + self.event_sheduler.register_area((64, 64, 32, 32), lambda _: self.dialogs_manager.start_dialog("test"), ["player"]) + + self.renderer.dialogs_box = pygame.image.load("assets/textures/GUI/dialogs_box.png").convert_alpha() def create_player_entity(self): """Crée une entité joueur.""" @@ -64,7 +66,7 @@ class Game(Engine): mob.set_default_life(5) mob.max_speed = 1. - mob.x, mob.y = 160, 16 + mob.x, mob.y = 1600, 16 def load_boss_fight_assets(self): """Charge les animations de combat des combats de boss.""" @@ -75,7 +77,7 @@ class Game(Engine): boss_none.load_animation_from_directory("assets/textures/boss_fight/boss_sprite/test/none") self.renderer.register_boss_fight_boss_animation(boss_none, "none") - self.renderer.boss_fight_GUI_container = pygame.image.load("assets/textures/boss_fight/fight_actions_GUI.png") + self.renderer.boss_fight_GUI_container = pygame.image.load("assets/textures/boss_fight/fight_actions_GUI.png").convert_alpha() game = Game()