diff --git a/src/Entity/Enemy.py b/src/Entity/Enemy.py index e8dedc9..d8b1e03 100644 --- a/src/Entity/Enemy.py +++ b/src/Entity/Enemy.py @@ -9,7 +9,6 @@ from src.Entity.Projectile import Projectile class Enemy(Entity): def __init__(self, enemy_data): self.size = enemy_data.get("size", [50, 50]) - print(self.size) super().__init__(self.size) # Base attributes diff --git a/src/Entity/Entity.py b/src/Entity/Entity.py index 08b878e..624bffa 100644 --- a/src/Entity/Entity.py +++ b/src/Entity/Entity.py @@ -11,6 +11,7 @@ class Entity(pygame.sprite.Sprite): self.pos = vec(pos) self.vel = vec(0, 0) self.acc = vec(0, 0) + self.alive = True # Default surface self.surf = pygame.Surface(size) diff --git a/src/Entity/Exit.py b/src/Entity/Exit.py index 2463ceb..11c2f68 100644 --- a/src/Entity/Exit.py +++ b/src/Entity/Exit.py @@ -24,9 +24,11 @@ class Exit(Entity): sprite_path (str, optional): Path to the sprite image for the exit """ super().__init__(pos=(x, y), size=(width, height), color=(0, 255, 0)) - self.next_level = next_level # Store the next level to load + self.next_level = next_level self.active = True # Flag to prevent multiple triggers - self.player = None # Will store the player reference + self.player = None + self.boss = None + self.locked = False # Load sprite if provided if sprite_path: @@ -46,16 +48,34 @@ class Exit(Entity): """ self.player = player + def set_boss(self, boss): + """ + Set the boss to this exit. The exit will be locked until the boss is defeated. + + Args: + boss: The boss entity to check defeat status with + """ + print("Setting boss for exit") + self.boss = boss + self.locked = True + def update(self): """ Check for collision with the player and trigger level completion. """ + # Check if the boss is defeated + if self.boss: + if hasattr(self.boss, "alive") and not self.boss.alive: + self.locked = False + elif not hasattr(self.boss, "alive"): + self.locked = False + # Skip collision check if player reference is not set if not self.player or not self.active: return # Check if player is colliding with exit - if self.rect.colliderect(self.player.rect): + if self.rect.colliderect(self.player.rect) and not self.locked: # Play the video and return to menu self.play_video_and_return_to_menu("assets/map/exit/Zeldo Motus.mp4") self.active = False # Prevent multiple triggers diff --git a/src/game.py b/src/game.py index 183afad..9112b60 100644 --- a/src/game.py +++ b/src/game.py @@ -61,6 +61,14 @@ def initialize_game(game_resources, map_file="map/levels/1.json"): for exit_obj in exits: exit_obj.set_player(map_objects["player"]) + enemies = map_objects.get("enemies", None) + if exits and enemies: + for enemy in enemies: + if hasattr(enemy, "enemy_type") and enemy.enemy_type == "boss": + for exit_obj in exits: + exit_obj.set_boss(enemy) + break + background = map_objects.get("background", None) # If no background is found, use a default black background diff --git a/src/handler.py b/src/handler.py index 7e3caef..e886459 100644 --- a/src/handler.py +++ b/src/handler.py @@ -505,39 +505,43 @@ def handle_exits(P1, exits, game_resources, level_file, speedrun_timer=None): """Handle collisions with level exits""" exits_hit = pygame.sprite.spritecollide(P1, exits, False) if exits else [] for exit in exits_hit: - if speedrun_timer and speedrun_timer.is_running: - collected_coins = speedrun_timer.collected_items - total_coins = speedrun_timer.total_items + if not exit.locked: + if speedrun_timer and speedrun_timer.is_running: + collected_coins = speedrun_timer.collected_items + total_coins = speedrun_timer.total_items - speedrun_timer.stop() - speedrun_timer.save_time(collected_coins, total_coins) - if hasattr(game_resources, "infinite_mode") and game_resources.infinite_mode: - # Infinite mode: load the next level without going back to menu - if hasattr(game_resources, "infinite_mode_db"): - # Zeldo : add 100 points - game_resources.infinite_mode_db.add_score("player", 100) - # Add coins points also - game_resources.infinite_mode_db.add_score("player", P1.coins * 10) - result = handle_exit_collision(exit, game_resources, level_file) - return {"action": "continue_infinite", "result": result} - else: - # Normal mode: unlock the next level and return to menu - current_level_match = re.search(r"(\d+)\.json$", level_file) - if current_level_match: - current_level = int(current_level_match.group(1)) - next_level = current_level + 1 + speedrun_timer.stop() + speedrun_timer.save_time(collected_coins, total_coins) + if ( + hasattr(game_resources, "infinite_mode") + and game_resources.infinite_mode + ): + # Infinite mode: load the next level without going back to menu + if hasattr(game_resources, "infinite_mode_db"): + # Zeldo : add 100 points + game_resources.infinite_mode_db.add_score("player", 100) + # Add coins points also + game_resources.infinite_mode_db.add_score("player", P1.coins * 10) + result = handle_exit_collision(exit, game_resources, level_file) + return {"action": "continue_infinite", "result": result} + else: + # Normal mode: unlock the next level and return to menu + current_level_match = re.search(r"(\d+)\.json$", level_file) + if current_level_match: + current_level = int(current_level_match.group(1)) + next_level = current_level + 1 - # Unlock next level - db = LevelDB() - db.unlock_level(next_level) - db.close() + # Unlock next level + db = LevelDB() + db.unlock_level(next_level) + db.close() - # Return to level select menu - return { - "action": "return_to_level_select", - "current_state": 0, # MENU - "current_menu": "level_select", - } + # Return to level select menu + return { + "action": "return_to_level_select", + "current_state": 0, # MENU + "current_menu": "level_select", + } return None