From 197a4ae7dc2ab00161e42e04e50ed48702baa681 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 08:55:04 +0100 Subject: [PATCH 01/14] Prevented Player from moving when dialog is occuring --- src/engine/event_handler.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/engine/event_handler.py b/src/engine/event_handler.py index 1568ed0..08cc424 100644 --- a/src/engine/event_handler.py +++ b/src/engine/event_handler.py @@ -74,6 +74,7 @@ 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: @@ -87,13 +88,13 @@ class EventHandler: self.hovered_area.remove(area) if self.engine.entity_manager.player_entity_name: - if K_RIGHT in self.key_pressed: + if K_RIGHT in self.key_pressed and not self.engine.dialogs_manager.reading_dialog: self.engine.entity_manager.move_player_controls(1, 0) - if K_LEFT in self.key_pressed: + if K_LEFT in self.key_pressed and not self.engine.dialogs_manager.reading_dialog: self.engine.entity_manager.move_player_controls(-1, 0) - if K_UP in self.key_pressed: + if K_UP in self.key_pressed and not self.engine.dialogs_manager.reading_dialog: self.engine.entity_manager.move_player_controls(0, -1) - if K_DOWN in self.key_pressed: + if K_DOWN in self.key_pressed and not self.engine.dialogs_manager.reading_dialog: self.engine.entity_manager.move_player_controls(0, 1) if K_SPACE in self.key_pressed: From e2a97c65fdbbbb8f21278f2cd37355f655a5f251 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 09:51:29 +0100 Subject: [PATCH 02/14] Added .lock() and .unlock() entity functions (Prevent them from moving) --- src/engine/entity.py | 64 +++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/src/engine/entity.py b/src/engine/entity.py index 392a884..56bf8a0 100644 --- a/src/engine/entity.py +++ b/src/engine/entity.py @@ -11,6 +11,8 @@ class Entity: self.x = 8 self.y = 8 + self.locked = False + self.direction = 0 # 0 : tourné vers la droite (ou sens par défaut), 1 : tourné vers la gauche (ou retourné) # Variables utilisées pour détecter les mouvements @@ -131,38 +133,46 @@ class Entity: y = y/initial_speed*self.max_speed # On simule le mouvement. Si on ne rencontre pas de collision, on applique le mouvement - if not self.get_collisions(self.x + x, self.y, map_manager): - self.x += x - else: - # Si on a une collision, on avance pixel par pixel jusqu'à atteindre la collision - i = 0 - if x > 0: - while not self.get_collisions(self.x + i, self.y, map_manager): - i += 1 - i -= 1 + if not self.locked: # Si l'entité n'est pas verrouillée on applique le movement + if not self.get_collisions(self.x + x, self.y, map_manager): + self.x += x else: - while not self.get_collisions(self.x + i, self.y, map_manager): + # Si on a une collision, on avance pixel par pixel jusqu'à atteindre la collision + i = 0 + if x > 0: + while not self.get_collisions(self.x + i, self.y, map_manager): + i += 1 i -= 1 - i += 1 - - self.x += i - - # On répète le procédé avec l'ordonnée - if not self.get_collisions(self.x, self.y + y, map_manager): - self.y += y - else: - i = 0 - if y > 0: - while not self.get_collisions(self.x, self.y + i, map_manager): + else: + while not self.get_collisions(self.x + i, self.y, map_manager): + i -= 1 i += 1 - i -= 1 - else: - while not self.get_collisions(self.x, self.y + i, map_manager): - i -= 1 - i += 1 - self.y += i + self.x += i + + # On répète le procédé avec l'ordonnée + if not self.get_collisions(self.x, self.y + y, map_manager): + self.y += y + else: + i = 0 + if y > 0: + while not self.get_collisions(self.x, self.y + i, map_manager): + i += 1 + i -= 1 + else: + while not self.get_collisions(self.x, self.y + i, map_manager): + i -= 1 + i += 1 + + self.y += i def link_animation(self, name: str): """Met à jour l'animation en cours de l'entité.""" self.animation_name = name + + + def lock(self): + self.locked = True + + def unlock(self): + self.locked = False \ No newline at end of file From afb2e2386fec74b29f98753fd9c6b32ccdbc5c61 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 09:52:04 +0100 Subject: [PATCH 03/14] Removed print when next dialog is called --- src/engine/dialogs_manager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/engine/dialogs_manager.py b/src/engine/dialogs_manager.py index 0faec80..377f482 100644 --- a/src/engine/dialogs_manager.py +++ b/src/engine/dialogs_manager.py @@ -31,8 +31,6 @@ class DialogsManager: else: self.next_dialog() - print("next") - def next_dialog(self): """Passe au dialogue suivant. Appelle le callback si le dialogue est fini.""" self.current_dialog_id += 1 From 83d51f3e5ed16f235c8b7c4708c49e02ff2a1dcb Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 09:53:44 +0100 Subject: [PATCH 04/14] Added .pause() and .resume() functions (Pause the game logic (Entites moving and damage) and lock player (Player movements doesn't seems to be affected by the pause of the update loop)) --- src/engine/entity_manager.py | 41 ++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/engine/entity_manager.py b/src/engine/entity_manager.py index 72e59a6..45fa572 100644 --- a/src/engine/entity_manager.py +++ b/src/engine/entity_manager.py @@ -8,6 +8,7 @@ class EntityManager: self.entities: dict[str:Entity] = {} self.player_entity_name = "" self.map_manager = map_manager + self.paused = False def register_entity(self, name: str) -> Entity: """Crée une entité et l'enregistre dans un dictionnaire.""" @@ -26,21 +27,22 @@ class EntityManager: def update(self, delta: float): """Met à jour toutes les entités enregistrées.""" - for entity_name in list(self.entities.keys()): - entity = self.entities[entity_name] - entity.update(delta) - if entity.life_points == 0: - self.entities.pop(entity_name) + if not self.paused: + for entity_name in list(self.entities.keys()): + entity = self.entities[entity_name] + entity.update(delta) + if entity.life_points == 0: + self.entities.pop(entity_name) - if entity.brain is not None: - entity.brain.update(delta) + if entity.brain is not None: + entity.brain.update(delta) - if self.player_entity_name: - player: Entity = self.get_by_name(self.player_entity_name) - if player.mouvements[0] != 0. or player.mouvements[1] != 0.: - player.link_animation("player_walking") - else: - player.link_animation("player_none") + if self.player_entity_name: + player: Entity = self.get_by_name(self.player_entity_name) + if player.mouvements[0] != 0. or player.mouvements[1] != 0.: + player.link_animation("player_walking") + else: + player.link_animation("player_none") def get_all_entities(self) -> list[Entity]: """Donne la liste de toutes les entités enregistrées.""" @@ -49,3 +51,16 @@ class EntityManager: def get_by_name(self, name: str) -> Entity: """Donne l'entité avec le nom donné.""" return self.entities[name] + + def pause(self): + self.paused = True + player: Entity = self.get_by_name(self.player_entity_name) + if not player.locked: + player.lock() + + + def resume(self): + self.paused = False + player: Entity = self.get_by_name(self.player_entity_name) + if player.locked: + player.unlock() \ No newline at end of file From ddb27bfd5a752d2c1c0b69a9ef58f1d5ab77b649 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 09:54:12 +0100 Subject: [PATCH 05/14] Added sync between dialogs and game pause --- src/engine/event_handler.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/engine/event_handler.py b/src/engine/event_handler.py index 08cc424..54756d5 100644 --- a/src/engine/event_handler.py +++ b/src/engine/event_handler.py @@ -88,13 +88,13 @@ class EventHandler: self.hovered_area.remove(area) if self.engine.entity_manager.player_entity_name: - if K_RIGHT in self.key_pressed and not self.engine.dialogs_manager.reading_dialog: + if K_RIGHT in self.key_pressed: self.engine.entity_manager.move_player_controls(1, 0) - if K_LEFT in self.key_pressed and not self.engine.dialogs_manager.reading_dialog: + if K_LEFT in self.key_pressed: self.engine.entity_manager.move_player_controls(-1, 0) - if K_UP in self.key_pressed and not self.engine.dialogs_manager.reading_dialog: + if K_UP in self.key_pressed: self.engine.entity_manager.move_player_controls(0, -1) - if K_DOWN in self.key_pressed and not self.engine.dialogs_manager.reading_dialog: + if K_DOWN in self.key_pressed: self.engine.entity_manager.move_player_controls(0, 1) if K_SPACE in self.key_pressed: @@ -116,3 +116,11 @@ class EventHandler: self.engine.camera.target_zoom *= 1.01 if K_c in self.key_pressed: self.engine.camera.target_zoom *= 0.99 + + if self.engine.dialogs_manager.reading_dialog: + if not self.engine.entity_manager.paused: + self.engine.entity_manager.pause() + else: + if self.engine.entity_manager.paused: + self.engine.entity_manager.resume() + From 15565c671203b6638556cc4cddb3efbe54b2ac54 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 09:55:24 +0100 Subject: [PATCH 06/14] Added Game satuts display in debug --- src/engine/renderer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/renderer.py b/src/engine/renderer.py index 4a3389e..5a75ac8 100644 --- a/src/engine/renderer.py +++ b/src/engine/renderer.py @@ -117,7 +117,7 @@ class Renderer: # Conteur de FPS en mode DEBUG if self.engine.DEBUG_MODE: - self.window.blit(font.SysFont("Arial", 20).render(f"FPS: {round(self.engine.clock.get_fps())}", True, (255, 0, 0)), + self.window.blit(font.SysFont("Arial", 20).render(f"FPS: {round(self.engine.clock.get_fps())}, Game Status: {'Paused' if self.engine.entity_manager.paused else 'Playing'}", True, (255, 0, 0)), (0, 0)) player = self.engine.entity_manager.get_by_name('player') self.window.blit(font.SysFont("Arial", 20).render(f"X: {round(player.x, 2)} Y:{round(player.y, 2)}", From 1f8444bc0bb597030b57a0c0e5a7ab8393306020 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 10:29:43 +0100 Subject: [PATCH 07/14] Edited .pause() function to lock all unlocked entity instead of blocking update function, and .resume() to unlock only non-locked entity before pause --- src/engine/entity_manager.py | 44 ++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/engine/entity_manager.py b/src/engine/entity_manager.py index 45fa572..b4016dc 100644 --- a/src/engine/entity_manager.py +++ b/src/engine/entity_manager.py @@ -8,6 +8,7 @@ class EntityManager: self.entities: dict[str:Entity] = {} self.player_entity_name = "" self.map_manager = map_manager + self.locked_before_pause: list[Entity] = [] self.paused = False def register_entity(self, name: str) -> Entity: @@ -27,22 +28,21 @@ class EntityManager: def update(self, delta: float): """Met à jour toutes les entités enregistrées.""" - if not self.paused: - for entity_name in list(self.entities.keys()): - entity = self.entities[entity_name] - entity.update(delta) - if entity.life_points == 0: - self.entities.pop(entity_name) + for entity_name in list(self.entities.keys()): + entity = self.entities[entity_name] + entity.update(delta) + if entity.life_points == 0: + self.entities.pop(entity_name) - if entity.brain is not None: - entity.brain.update(delta) + if entity.brain is not None: + entity.brain.update(delta) - if self.player_entity_name: - player: Entity = self.get_by_name(self.player_entity_name) - if player.mouvements[0] != 0. or player.mouvements[1] != 0.: - player.link_animation("player_walking") - else: - player.link_animation("player_none") + if self.player_entity_name: + player: Entity = self.get_by_name(self.player_entity_name) + if player.mouvements[0] != 0. or player.mouvements[1] != 0.: + player.link_animation("player_walking") + else: + player.link_animation("player_none") def get_all_entities(self) -> list[Entity]: """Donne la liste de toutes les entités enregistrées.""" @@ -53,14 +53,18 @@ class EntityManager: return self.entities[name] def pause(self): + for e in self.get_all_entities(): + if e.locked: + self.locked_before_pause.append(e) + else: + e.lock() self.paused = True - player: Entity = self.get_by_name(self.player_entity_name) - if not player.locked: - player.lock() def resume(self): + for e in self.get_all_entities(): + if not e in self.locked_before_pause: + e.unlock() + self.paused = False - player: Entity = self.get_by_name(self.player_entity_name) - if player.locked: - player.unlock() \ No newline at end of file + self.locked_before_pause = [] \ No newline at end of file From e8343160d4905b899637bdf83a2e9674813441ab Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 10:30:34 +0100 Subject: [PATCH 08/14] Edited lock to block all interraction including animation instead of just the movements --- src/engine/entity.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/engine/entity.py b/src/engine/entity.py index 56bf8a0..12f94e5 100644 --- a/src/engine/entity.py +++ b/src/engine/entity.py @@ -119,21 +119,23 @@ class Entity: def move(self, x: float, y: float, map_manager: MapManager): """Fait bouger l'entité en tenant compte des collisions.""" - # On vérifie le sens du mouvement pour changer self.direction - if x > 0: - self.direction = 0 - elif x < 0: - self.direction = 1 - # On ne met pas de else car si x = 0, on ne change pas de direction + if not self.locked: # Si l'entité n'est pas verrouillée on calcul le mouvement + + # On vérifie le sens du mouvement pour changer self.direction + if x > 0: + self.direction = 0 + elif x < 0: + self.direction = 1 + # On ne met pas de else car si x = 0, on ne change pas de direction - # On normalise la vitesse - initial_speed = math.sqrt(x**2+y**2) + # On normalise la vitesse + initial_speed = math.sqrt(x**2+y**2) - x = x/initial_speed*self.max_speed - y = y/initial_speed*self.max_speed + x = x/initial_speed*self.max_speed + y = y/initial_speed*self.max_speed - # On simule le mouvement. Si on ne rencontre pas de collision, on applique le mouvement - if not self.locked: # Si l'entité n'est pas verrouillée on applique le movement + # On simule le mouvement. Si on ne rencontre pas de collision, on applique le mouvement + if not self.get_collisions(self.x + x, self.y, map_manager): self.x += x else: From 8cbe1a3727cd7ad2e3401065ce1fc50d65f473b7 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 10:41:57 +0100 Subject: [PATCH 09/14] Edited default zoom value --- src/engine/camera.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/camera.py b/src/engine/camera.py index 9be655f..3c992b3 100644 --- a/src/engine/camera.py +++ b/src/engine/camera.py @@ -5,7 +5,7 @@ class Camera: def __init__(self): self.x = 0 self.y = 0 - self.zoom = 1. + self.zoom = 1.75 # Décalage lors du mouvement du joueur self.player_moving_offset = 100 From 9e400598a3205c3c5ad3f9f553dc0513ccd878f8 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 10:42:26 +0100 Subject: [PATCH 10/14] Imported whole engine and moved pause() handling from event_handler --- src/engine/dialogs_manager.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/engine/dialogs_manager.py b/src/engine/dialogs_manager.py index 377f482..85c9e73 100644 --- a/src/engine/dialogs_manager.py +++ b/src/engine/dialogs_manager.py @@ -1,14 +1,13 @@ import json from types import FunctionType -from src.engine.event_handler import EventHandler +from src.engine.engine import Engine class DialogsManager: """Classe qui gère la lecture des dialogues.""" - def __init__(self, event_handler: EventHandler): - self.event_handler = event_handler - + def __init__(self, engine: 'Engine'): + self.engine = engine self.current_dialogs = [] self.current_dialog_id = -1 self.dialogs = {} @@ -41,7 +40,8 @@ class DialogsManager: self.current_dialog_id = -1 self.writing_dialog = False self.reading_dialog = False - self.event_handler.remove_button_area("next_dialog") + self.engine.entity_manager.resume() + self.engine.event_handler.remove_button_area("next_dialog") if self.dialogue_finished_callback is not None: self.dialogue_finished_callback() @@ -50,7 +50,9 @@ class DialogsManager: # Si un dialogue n'est pas déja lancé, on lance le dialogue au nom donné if not self.reading_dialog: - self.event_handler.register_button_area((0, 0, 1, 1), self.next_signal, "next_dialog", 2) + self.engine.entity_manager.pause() + + self.engine.event_handler.register_button_area((0, 0, 1, 1), self.next_signal, "next_dialog", 2) self.current_dialogs = self.dialogs[name] self.current_dialog_id = 0 From f5c1f8bc6394b586daeba38c82a28630e567b1a3 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 10:42:42 +0100 Subject: [PATCH 11/14] Moved pause to dialogs_manager --- src/engine/event_handler.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/engine/event_handler.py b/src/engine/event_handler.py index 54756d5..c2408f0 100644 --- a/src/engine/event_handler.py +++ b/src/engine/event_handler.py @@ -112,15 +112,8 @@ class EventHandler: print(f"Player pos: X = {self.engine.entity_manager.get_by_name('player').x} " f"Y = {self.engine.entity_manager.get_by_name('player').y}") - if K_x in self.key_pressed: - self.engine.camera.target_zoom *= 1.01 - if K_c in self.key_pressed: - self.engine.camera.target_zoom *= 0.99 - - if self.engine.dialogs_manager.reading_dialog: - if not self.engine.entity_manager.paused: - self.engine.entity_manager.pause() - else: - if self.engine.entity_manager.paused: - self.engine.entity_manager.resume() + if K_x in self.key_pressed: + self.engine.camera.target_zoom *= 1.01 + if K_c in self.key_pressed: + self.engine.camera.target_zoom *= 0.99 From ce14e45e8f07c9e5573c094cc943a2fbdb5b4613 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 10:50:54 +0100 Subject: [PATCH 12/14] Fixed engine import --- src/engine/dialogs_manager.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/engine/dialogs_manager.py b/src/engine/dialogs_manager.py index 85c9e73..f32d605 100644 --- a/src/engine/dialogs_manager.py +++ b/src/engine/dialogs_manager.py @@ -1,12 +1,10 @@ import json from types import FunctionType - -from src.engine.engine import Engine - +import src.engine.engine as engine class DialogsManager: """Classe qui gère la lecture des dialogues.""" - def __init__(self, engine: 'Engine'): + def __init__(self, engine: 'engine.Engine'): self.engine = engine self.current_dialogs = [] self.current_dialog_id = -1 From 67fef0b82ecaf40706eedcbbd5edab6afab34ca3 Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 10:51:14 +0100 Subject: [PATCH 13/14] Edited dialogs_manager import --- src/engine/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/engine.py b/src/engine/engine.py index 0abcc69..1aa6c61 100644 --- a/src/engine/engine.py +++ b/src/engine/engine.py @@ -36,7 +36,7 @@ class Engine: self.entity_manager = EntityManager(self.map_manager) self.boss_fight_manager = BossFightManager(self) self.event_sheduler = EventSheduler(self) - self.dialogs_manager = DialogsManager(self.event_handler) + self.dialogs_manager = DialogsManager(self) self.menu_manager = MenuManager(self) self.sound_manager = SoundManager(60) From daa7ca46d41647935f8acf0c07864076f0304b8b Mon Sep 17 00:00:00 2001 From: adastram Date: Thu, 11 Jan 2024 10:58:56 +0100 Subject: [PATCH 14/14] Added doc string --- src/engine/entity.py | 6 ++++-- src/engine/entity_manager.py | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/engine/entity.py b/src/engine/entity.py index 12f94e5..9b7e571 100644 --- a/src/engine/entity.py +++ b/src/engine/entity.py @@ -11,7 +11,7 @@ class Entity: self.x = 8 self.y = 8 - self.locked = False + self.locked = False # Variable définissant si l'entité est bloqué ou non (.lock() et .unlock()) self.direction = 0 # 0 : tourné vers la droite (ou sens par défaut), 1 : tourné vers la gauche (ou retourné) @@ -169,12 +169,14 @@ class Entity: self.y += i def link_animation(self, name: str): - """Met à jour l'animation en cours de l'entité.""" + """Met à jour l'animation en cours de l'entitée.""" self.animation_name = name def lock(self): + """Bloque tout les mouvements de l'entitée""" self.locked = True def unlock(self): + """Débloque tout les mouvements de l'entitée""" self.locked = False \ No newline at end of file diff --git a/src/engine/entity_manager.py b/src/engine/entity_manager.py index b4016dc..6b45414 100644 --- a/src/engine/entity_manager.py +++ b/src/engine/entity_manager.py @@ -34,7 +34,7 @@ class EntityManager: if entity.life_points == 0: self.entities.pop(entity_name) - if entity.brain is not None: + if entity.brain is not None and not self.paused: entity.brain.update(delta) if self.player_entity_name: @@ -53,6 +53,7 @@ class EntityManager: return self.entities[name] def pause(self): + """Met en pause tout les mouvements de toutes les entitées""" for e in self.get_all_entities(): if e.locked: self.locked_before_pause.append(e) @@ -62,6 +63,7 @@ class EntityManager: def resume(self): + """Reprend les mouvement de toutes les entitées qui n'étaient pas lock avant l'appel de .pause()""" for e in self.get_all_entities(): if not e in self.locked_before_pause: e.unlock()