sep-pm-platformer/project/level/selection/LevelSelectionScreenManager.py

164 lines
6.6 KiB
Python

from typing import Optional
import pygame.time
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
from sprite.SpritesheetManager import SpritesheetManager
from sprite.StaticSprite import StaticSprite
from ui_elements.ClickEvent import ClickEvent
from ui_elements.KeyManager import KeyManager
from ui_elements.TextLabel import TextLabel
LABEL_COUNT = 10
OFFSET = (50, 20)
class LevelSelectionScreenManager(ScreenManager):
def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, main_loop,
level_manager: LevelManager):
super().__init__(sprite_manager, spritesheet_manager, main_loop)
self.level_manager = level_manager
self.levels_by_theme = self.level_manager.get_levels_by_theme()
self.themes = ConstantsParser.CONFIG.themes
self.level_labels: list[TextLabel] = []
self.theme_label: Optional[TextLabel] = None
self.selected_theme = self.themes[0]
self.key_input_delay = -1
def select_next_theme(self, click=None):
if click is None or click.is_click_down(ClickEvent.CLICK_LEFT):
index = (self.themes.index(self.selected_theme) + 1) % len(self.themes)
self.select_theme(self.themes[index])
def select_prev_theme(self, click=None):
if click is None or click.is_click_down(ClickEvent.CLICK_LEFT):
index = self.themes.index(self.selected_theme) - 1
if index < 0:
index = len(self.themes) - 1
self.select_theme(self.themes[index])
def select_level(self, click: ClickEvent, level: Level):
if click.is_click_down(ClickEvent.CLICK_LEFT):
self.main_loop.select_level(level)
def go_to_menu(self, click):
if click.is_click_down(ClickEvent.CLICK_LEFT):
self.main_loop.select_main_menu()
def initialize(self):
arrow_left = StaticSprite(self.spritesheet_manager.get_sheet('ui_arrow'))
arrow_left.set_animation_state('right')
arrow_left.position_scale = PositionScale((OFFSET[0], OFFSET[1]), (1.8, 1.8))
arrow_left.add_click_listener(self.select_prev_theme)
self.add_element(DrawLayers.UI, arrow_left)
arrow_right = StaticSprite(self.spritesheet_manager.get_sheet('ui_arrow'))
arrow_right.set_animation_state('left')
arrow_right.position_scale = PositionScale((OFFSET[0] + 50, OFFSET[1]), (1.8, 1.8))
arrow_right.add_click_listener(self.select_next_theme)
self.add_element(DrawLayers.UI, arrow_right)
self.theme_label = TextLabel('', OFFSET[0] + 120, OFFSET[1] - 2, font_size=65)
self.theme_label.position_scale.scale = (0.5, 0.5)
self.add_element(DrawLayers.UI, self.theme_label)
self.back_button = TextLabel('BACK [ESC]', 610, 430, font_size=30)
self.back_button.position_scale.scale = (0.5, 0.5)
self.add_element(DrawLayers.UI, self.back_button)
self.back_button.add_click_listener(lambda click: self.go_to_menu(click))
for i in range(0, LABEL_COUNT):
label = TextLabel(str(i), OFFSET[0] + 30, OFFSET[1] + 60 + i * 50, font_size=65)
label.position_scale.scale = (0.5, 0.5)
self.level_labels.append(label)
self.add_element(DrawLayers.UI, label)
self.select_theme(self.selected_theme)
def select_theme(self, theme: str):
self.selected_theme = theme
self.theme_label.set_text(theme)
for label in self.level_labels:
label.set_text('')
label.click_listeners = []
levels = self.levels_by_theme[self.selected_theme]
if len(levels) > 0:
self.level_labels[0].set_text(levels[0].name)
self.level_labels[0].add_click_listener(
lambda click: self.select_level(click, levels[0])
)
if len(levels) > 1:
self.level_labels[1].set_text(levels[1].name)
self.level_labels[1].add_click_listener(
lambda click: self.select_level(click, levels[1])
)
if len(levels) > 2:
self.level_labels[2].set_text(levels[2].name)
self.level_labels[2].add_click_listener(
lambda click: self.select_level(click, levels[2])
)
if len(levels) > 3:
self.level_labels[3].set_text(levels[3].name)
self.level_labels[3].add_click_listener(
lambda click: self.select_level(click, levels[3])
)
if len(levels) > 4:
self.level_labels[4].set_text(levels[4].name)
self.level_labels[4].add_click_listener(
lambda click: self.select_level(click, levels[4])
)
if len(levels) > 5:
self.level_labels[5].set_text(levels[5].name)
self.level_labels[5].add_click_listener(
lambda click: self.select_level(click, levels[5])
)
if len(levels) > 6:
self.level_labels[6].set_text(levels[6].name)
self.level_labels[6].add_click_listener(
lambda click: self.select_level(click, levels[6])
)
if len(levels) > 7:
self.level_labels[7].set_text(levels[7].name)
self.level_labels[7].add_click_listener(
lambda click: self.select_level(click, levels[7])
)
if len(levels) > 8:
self.level_labels[8].set_text(levels[8].name)
self.level_labels[8].add_click_listener(
lambda click: self.select_level(click, levels[8])
)
if len(levels) > 9:
self.level_labels[9].set_text(levels[9].name)
self.level_labels[9].add_click_listener(
lambda click: self.select_level(click, levels[9])
)
def destroy(self):
super().destroy()
def tick(self, tick_data: TickData):
if self.key_input_delay >= 0:
self.key_input_delay -= tick_data.dt
if self.key_input_delay <= 0:
if tick_data.key_manager.is_keymap_down(KeyManager.KEY_ESCAPE):
self.main_loop.select_main_menu()
elif tick_data.key_manager.is_keymap_down(KeyManager.KEY_LEFT):
self.select_prev_theme()
self.key_input_delay = 5
elif tick_data.key_manager.is_keymap_down(KeyManager.KEY_RIGHT):
self.select_next_theme()
self.key_input_delay = 5