diff --git a/project/data/config/config.json b/project/data/config/config.json index 93ef4f9..19b8bdf 100644 --- a/project/data/config/config.json +++ b/project/data/config/config.json @@ -8,5 +8,10 @@ 60, 40 ] - } + }, + "themes": [ + "tutorial", + "cave", + "castle" + ] } \ No newline at end of file diff --git a/project/level/LevelManager.py b/project/level/LevelManager.py index 9069e29..8c64292 100644 --- a/project/level/LevelManager.py +++ b/project/level/LevelManager.py @@ -1,6 +1,8 @@ import json +from typing import Optional from level.Level import Level +from physics import ConstantsParser class LevelManager: @@ -34,4 +36,20 @@ class LevelManager: levels_by_theme[level.theme].append(level) return levels_by_theme + def find_next_level(self, level: Level) -> Optional[Level]: + """ + Find the next element in the theme using THEME. If the last element from a theme is reached, the first element + of the next theme is returned. If the last THEME is reached, return None. + :param level: The level to find the next level from + :return: The next level or None + """ + levels_by_theme = self.get_levels_by_theme() + theme_index = ConstantsParser.CONFIG.themes.index(level.theme) + level_index = levels_by_theme[level.theme].index(level) + if level_index + 1 < len(levels_by_theme[level.theme]): + return levels_by_theme[level.theme][level_index + 1] + elif theme_index + 1 < len(ConstantsParser.CONFIG.themes): + return levels_by_theme[ConstantsParser.CONFIG.themes[theme_index + 1]][0] + else: + return None diff --git a/project/level/elements/static/GoalDoorReceiverLevelElement.py b/project/level/elements/static/GoalDoorReceiverLevelElement.py index 2353fa5..2b3dd98 100644 --- a/project/level/elements/static/GoalDoorReceiverLevelElement.py +++ b/project/level/elements/static/GoalDoorReceiverLevelElement.py @@ -1,12 +1,14 @@ from level.Level import Level from level.elements.static.ReceiverLevelElement import ReceiverLevelElement from physics.SpriteManager import SpriteManager +from physics.TickData import TickData from sprite.SpritesheetManager import SpritesheetManager class GoalDoorReceiverLevelElement(ReceiverLevelElement): def __init__(self, tile: dict, level: Level, level_screen_manager: 'LevelScreenManager'): super().__init__(tile, level, level_screen_manager) + self.is_collider = False def load(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, level: Level): self.spritesheet = spritesheet_manager.get_sheet('goal_door') @@ -17,4 +19,11 @@ class GoalDoorReceiverLevelElement(ReceiverLevelElement): super().set_active(active) self.set_animation_state('open' if self.active_state else 'close') self.is_collider = False - self.register_collisions = not self.active_state + self.register_collisions = self.active_state + + def tick(self, tick_data: TickData): + super().tick(tick_data) + for collision in self.get_collides_with(): + if collision.secondary_sprite.id == 'player': + if self.active_state: + self.level_screen_manager.player_success() diff --git a/project/level/selection/LevelScreenManager.py b/project/level/selection/LevelScreenManager.py index 9b1af17..e6799ac 100644 --- a/project/level/selection/LevelScreenManager.py +++ b/project/level/selection/LevelScreenManager.py @@ -32,3 +32,6 @@ class LevelScreenManager(ScreenManager): def player_death(self): self.main_loop.player_death(self.level) + + def player_success(self): + self.main_loop.player_success(self.level) diff --git a/project/level/selection/LevelSelectionScreenManager.py b/project/level/selection/LevelSelectionScreenManager.py index dcb6b83..0c069c2 100644 --- a/project/level/selection/LevelSelectionScreenManager.py +++ b/project/level/selection/LevelSelectionScreenManager.py @@ -3,6 +3,7 @@ from typing import Optional from level.Level import Level from level.LevelManager import LevelManager from level.selection.ScreenManager import ScreenManager +from physics import ConstantsParser from physics.SpriteManager import SpriteManager, DrawLayers from physics.TickData import TickData from sprite.PositionScale import PositionScale @@ -23,7 +24,7 @@ class LevelSelectionScreenManager(ScreenManager): self.level_manager = level_manager self.levels_by_theme = self.level_manager.get_levels_by_theme() - self.themes = ['tutorial', 'cave', 'castle'] + self.themes = ConstantsParser.CONFIG.themes self.level_labels: list[TextLabel] = [] self.theme_label: Optional[TextLabel] = None @@ -137,4 +138,4 @@ class LevelSelectionScreenManager(ScreenManager): def tick(self, tick_data: TickData): if tick_data.key_manager.is_keymap_down(KeyManager.KEY_ESCAPE): - self.main_loop.select_main_menu() \ No newline at end of file + self.main_loop.select_main_menu() diff --git a/project/main.py b/project/main.py index 08b315c..64d16b8 100644 --- a/project/main.py +++ b/project/main.py @@ -103,6 +103,10 @@ class MainLoop: def player_death(self, level: Level): self.select_level(level) + def player_success(self, level: Level): + next_level = self.parsed_levels_manager.find_next_level(level) + self.select_level(next_level) + def select_main_menu(self): self.set_game_state(self.GAME_STATE_MENU) diff --git a/project/physics/ConstantsParser.py b/project/physics/ConstantsParser.py index 9441b72..196a848 100644 --- a/project/physics/ConstantsParser.py +++ b/project/physics/ConstantsParser.py @@ -6,6 +6,7 @@ class ConstantsParser: parsed = json.load(open(file)) self.level_size = (parsed['level']['level_size'][0], parsed['level']['level_size'][1]) self.block_size = (parsed['level']['block_size'][0], parsed['level']['block_size'][1]) + self.themes = parsed['themes'] CONFIG = ConstantsParser("data/config/config.json")