Introduced screen layouts and game states
parent
2280e81629
commit
e50d280afa
|
@ -5,13 +5,13 @@
|
||||||
#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,L,,,,,,,,,,,,,,,,,,,,,,,,C,,,#
|
#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,L,,,,,M,M,,,,,,,,,,,,,,,,,,C,,,#
|
||||||
#,#,S,,,,,,,,,,,,,,,,,,,+,+,+,+,S,S,S,S,S,+,+,+,+,+,S,S,S,S,S,+,+,+,+,+,S,S,S,S,S,+,+,+,+,+,+,+,+,+,#
|
#,#,S,,,,,,,,,,,,,,,,,,,+,+,+,+,S,S,S,S,S,+,+,+,+,+,S,S,S,S,S,+,+,+,+,+,S,S,S,S,S,+,+,+,+,+,+,+,+,+,#
|
||||||
#,#,S,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
#,#,S,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||||
#,#,S,,,,,,,,,,,,,,,,,,,,,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,#,S,,,,,,,,,,,,,,,,,,,,,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,#,S,,,,,,,,,,,,,,,,,,,,,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,#,S,,,,,,,,,,,,,,,,,,,,,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,#,,,,,,,,,,,,,,,,,,,,,,G,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,#,,,,,,,,,,,,,,,,,,,,,,G,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,,,,,,,,,,,,,,,M,,,M,M,,M,,,,,,,,,,,,,,,,,M,,,,,,M,,,,,,,,,,,,,,,#
|
#,,,,,,,,,,,,,,,M,,,,,,M,,,,,,,,,,,,,,,,,M,,,,,,M,,,,,,,,,,,,,,,#
|
||||||
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,,,,,,,,,,,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,,,,,,,,,,,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
#,L,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
#,L,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
|
||||||
|
|
|
|
@ -15,7 +15,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "level-02",
|
"name": "level-02",
|
||||||
"theme": "castle",
|
"theme": "cave",
|
||||||
"abilities": [
|
"abilities": [
|
||||||
],
|
],
|
||||||
"file": "level-02.csv"
|
"file": "level-02.csv"
|
||||||
|
|
|
@ -834,5 +834,26 @@
|
||||||
"height": 36
|
"height": 36
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ui_arrow",
|
||||||
|
"subsheets": [
|
||||||
|
{
|
||||||
|
"id": "left",
|
||||||
|
"delays": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"width": 12,
|
||||||
|
"height": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "right",
|
||||||
|
"delays": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"width": 12,
|
||||||
|
"height": 12
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -25,3 +25,13 @@ class LevelManager:
|
||||||
filtered_row = list(map(lambda x: x.replace('\n', ''), split_row))
|
filtered_row = list(map(lambda x: x.replace('\n', ''), split_row))
|
||||||
csv_array.append(filtered_row)
|
csv_array.append(filtered_row)
|
||||||
return csv_array
|
return csv_array
|
||||||
|
|
||||||
|
def get_levels_by_theme(self) -> dict[str, list[Level]]:
|
||||||
|
levels_by_theme = {}
|
||||||
|
for level in self.levels:
|
||||||
|
if level.theme not in levels_by_theme:
|
||||||
|
levels_by_theme[level.theme] = []
|
||||||
|
levels_by_theme[level.theme].append(level)
|
||||||
|
return levels_by_theme
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from level.Level import Level
|
from level.Level import Level
|
||||||
from ui_elements.Background import Background
|
from ui_elements.ColoredRectangleUiElement import ColoredRectangleUiElement
|
||||||
from ui_elements.ClickEvent import ClickEvent
|
from ui_elements.ClickEvent import ClickEvent
|
||||||
from ui_elements.TextLabel import TextLabel
|
from ui_elements.TextLabel import TextLabel
|
||||||
|
|
||||||
|
@ -11,23 +11,27 @@ class LevelMenu:
|
||||||
def __init__(self, levels: [Level], x_pos: float, y_pos: float, width: float, height: float, column_count: int):
|
def __init__(self, levels: [Level], x_pos: float, y_pos: float, width: float, height: float, column_count: int):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.levels = levels
|
self.levels = levels
|
||||||
self.x_pos = x_pos
|
|
||||||
self.y_pos = y_pos
|
|
||||||
self.level_select_listener = lambda selected_level: None
|
self.level_select_listener = lambda selected_level: None
|
||||||
self.level_text_labels = []
|
self.level_text_labels = []
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.column_count = column_count
|
self.column_count = column_count
|
||||||
|
|
||||||
|
self.position = (x_pos, y_pos)
|
||||||
|
|
||||||
self.create_level_text_labels()
|
self.create_level_text_labels()
|
||||||
self.background = Background(self.x_pos, self.y_pos, self.width, self.height, (100, 100, 100, 180))
|
self.background = ColoredRectangleUiElement(self.width, self.height, (100, 100, 100, 180))
|
||||||
|
self.background.position_scale.position = self.position
|
||||||
|
|
||||||
def create_level_text_labels(self):
|
def create_level_text_labels(self):
|
||||||
current_text_label_x = self.x_pos
|
current_text_label_position = [self.position[0], self.position[1]]
|
||||||
current_text_label_y = self.y_pos
|
|
||||||
|
|
||||||
for index, level in enumerate(self.levels):
|
for index, level in enumerate(self.levels):
|
||||||
text_label = TextLabel(level.name, current_text_label_x, current_text_label_y, 60)
|
text_label = TextLabel(level.name,
|
||||||
|
current_text_label_position[0],
|
||||||
|
current_text_label_position[1],
|
||||||
|
60)
|
||||||
|
|
||||||
text_label.position_scale.scale = (0.5, 0.5)
|
text_label.position_scale.scale = (0.5, 0.5)
|
||||||
text_label.add_click_listener(
|
text_label.add_click_listener(
|
||||||
lambda click_event, selected_level=level:
|
lambda click_event, selected_level=level:
|
||||||
|
@ -36,10 +40,10 @@ class LevelMenu:
|
||||||
self.level_text_labels.append(text_label)
|
self.level_text_labels.append(text_label)
|
||||||
|
|
||||||
if (index + 1) % self.column_count == 0:
|
if (index + 1) % self.column_count == 0:
|
||||||
current_text_label_y += self.height / (len(self.levels) / self.column_count)
|
current_text_label_position[0] = self.position[0]
|
||||||
current_text_label_x = self.x_pos
|
current_text_label_position[1] += self.height / (len(self.levels) / self.column_count)
|
||||||
else:
|
else:
|
||||||
current_text_label_x += self.width / self.column_count
|
current_text_label_position[0] += self.width / self.column_count
|
||||||
|
|
||||||
def handle_level_text_label_click(self, click_event: ClickEvent, level: Level):
|
def handle_level_text_label_click(self, click_event: ClickEvent, level: Level):
|
||||||
if click_event.event.type == pygame.MOUSEBUTTONUP:
|
if click_event.event.type == pygame.MOUSEBUTTONUP:
|
|
@ -0,0 +1,16 @@
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from level.selection.ScreenManager import ScreenManager
|
||||||
|
from physics.SpriteManager import SpriteManager
|
||||||
|
from sprite.SpritesheetManager import SpritesheetManager
|
||||||
|
|
||||||
|
|
||||||
|
class LevelScreenManager(ScreenManager):
|
||||||
|
def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, main_loop):
|
||||||
|
super().__init__(sprite_manager, spritesheet_manager, main_loop)
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
super().destroy()
|
|
@ -0,0 +1,79 @@
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from level.Level import Level
|
||||||
|
from level.LevelManager import LevelManager
|
||||||
|
from level.selection.ScreenManager import ScreenManager
|
||||||
|
from physics.SpriteManager import SpriteManager, DrawLayers
|
||||||
|
from sprite.PositionScale import PositionScale
|
||||||
|
from sprite.SpritesheetManager import SpritesheetManager
|
||||||
|
from sprite.StaticSprite import StaticSprite
|
||||||
|
from ui_elements.ClickEvent import ClickEvent
|
||||||
|
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 = ['tutorial', 'cave', 'castle']
|
||||||
|
|
||||||
|
self.level_labels: list[TextLabel] = []
|
||||||
|
|
||||||
|
self.selected_theme = self.themes[0]
|
||||||
|
|
||||||
|
def select_next_theme(self, click: ClickEvent):
|
||||||
|
if 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):
|
||||||
|
if 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 initialize(self):
|
||||||
|
arrow_left = StaticSprite(self.spritesheet_manager.get_sheet('ui_arrow'))
|
||||||
|
arrow_left.set_animation_state('left')
|
||||||
|
arrow_left.position_scale = PositionScale((OFFSET[0], OFFSET[1]), (3, 3))
|
||||||
|
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('right')
|
||||||
|
arrow_right.position_scale = PositionScale((OFFSET[0] + 50, OFFSET[1]), (3, 3))
|
||||||
|
arrow_right.add_click_listener(self.select_next_theme)
|
||||||
|
self.add_element(DrawLayers.UI, arrow_right)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
for label in self.level_labels:
|
||||||
|
label.set_text('')
|
||||||
|
label.click_listeners = []
|
||||||
|
|
||||||
|
for id, level in enumerate(self.levels_by_theme[self.selected_theme]):
|
||||||
|
self.level_labels[id].set_text(level.name)
|
||||||
|
self.level_labels[id].add_click_listener(lambda click: self.select_level(click, level))
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
super().destroy()
|
|
@ -0,0 +1,16 @@
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from level.selection.ScreenManager import ScreenManager
|
||||||
|
from physics.SpriteManager import SpriteManager
|
||||||
|
from sprite.SpritesheetManager import SpritesheetManager
|
||||||
|
|
||||||
|
|
||||||
|
class MainMenuScreenManager(ScreenManager):
|
||||||
|
def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager,main_loop):
|
||||||
|
super().__init__(sprite_manager, spritesheet_manager, main_loop)
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
super().destroy()
|
|
@ -0,0 +1,26 @@
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from physics.SpriteManager import SpriteManager
|
||||||
|
from sprite.SpritesheetManager import SpritesheetManager
|
||||||
|
from ui_elements.UiElement import UiElement
|
||||||
|
|
||||||
|
|
||||||
|
class ScreenManager:
|
||||||
|
def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, main_loop):
|
||||||
|
self.sprite_manager = sprite_manager
|
||||||
|
self.spritesheet_manager = spritesheet_manager
|
||||||
|
self.main_loop = main_loop
|
||||||
|
|
||||||
|
self.elements: list[UiElement] = []
|
||||||
|
|
||||||
|
def add_element(self, layer: str, ui_element: UiElement):
|
||||||
|
self.elements.append(ui_element)
|
||||||
|
self.sprite_manager.add_ui_element(layer, ui_element)
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def initialize(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
for element in self.elements:
|
||||||
|
self.sprite_manager.remove_ui_element(element)
|
247
project/main.py
247
project/main.py
|
@ -1,98 +1,126 @@
|
||||||
import random
|
from typing import Optional
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
|
from level.Level import Level
|
||||||
from level.LevelManager import LevelManager
|
from level.LevelManager import LevelManager
|
||||||
from level.elements.LoadedLevel import LoadedLevel
|
from level.elements.LoadedLevel import LoadedLevel
|
||||||
|
from level.selection.LevelScreenManager import LevelScreenManager
|
||||||
|
from level.selection.LevelSelectionScreenManager import LevelSelectionScreenManager
|
||||||
|
from level.selection.MainMenuScreenManager import MainMenuScreenManager
|
||||||
|
from level.selection.ScreenManager import ScreenManager
|
||||||
from physics import ConstantsParser
|
from physics import ConstantsParser
|
||||||
from physics.SpriteManager import SpriteManager, DrawLayers
|
from physics.SpriteManager import SpriteManager
|
||||||
from physics.TickData import TickData
|
from physics.TickData import TickData
|
||||||
from physics.sprites.PlayerSprite import PlayerSprite
|
|
||||||
from sprite.PositionScale import PositionScale
|
from sprite.PositionScale import PositionScale
|
||||||
from sprite.Sprite import Sprite
|
|
||||||
from sprite.SpritesheetManager import SpritesheetManager
|
from sprite.SpritesheetManager import SpritesheetManager
|
||||||
from sprite.StaticSprite import StaticSprite
|
|
||||||
from ui_elements.ClickEvent import ClickEvent
|
from ui_elements.ClickEvent import ClickEvent
|
||||||
from ui_elements.KeyManager import KeyManager
|
from ui_elements.KeyManager import KeyManager
|
||||||
from ui_elements.LevelMenu import LevelMenu
|
|
||||||
from ui_elements.TextLabel import TextLabel
|
|
||||||
|
|
||||||
what_to_run = 'level'
|
what_to_run = 'level'
|
||||||
|
|
||||||
WIDTH = 12 * 71 * 1.5
|
DEPRECATED_WIDTH = 12 * 71 * 1.5
|
||||||
HEIGHT = 12 * 40 * 1.5
|
DEPRECATED_HEIGHT = 12 * 40 * 1.5
|
||||||
|
|
||||||
# Background to test for level design
|
# Background to test for level design
|
||||||
test_background_castle = pygame.transform.scale(pygame.image.load('data/sprites/castle_bg.png'), (WIDTH, HEIGHT))
|
test_background_castle = pygame.transform.scale(pygame.image.load('data/sprites/castle_bg.png'),
|
||||||
# test_background_cave = pygame.transform.scale(pygame.image.load('data/sprites/cave_bg.png'), (WIDTH, HEIGHT))
|
(DEPRECATED_WIDTH, DEPRECATED_HEIGHT))
|
||||||
# test_background_tutorial = pygame.transform.scale(pygame.image.load('data/sprites/tutorial_bg.png'), (WIDTH, HEIGHT))
|
|
||||||
|
|
||||||
|
|
||||||
|
# test_background_castle = pygame.transform.scale(pygame.image.load('data/sprites/cave_bg.png'), (DEPRECATED_WIDTH, DEPRECATED_WIDTH))
|
||||||
|
# test_background_tutorial = pygame.transform.scale(pygame.image.load('data/sprites/tutorial_bg.png'), (DEPRECATED_WIDTH, DEPRECATED_WIDTH))
|
||||||
|
|
||||||
def apply_frame_rate(number: float):
|
|
||||||
|
def apply_frame_rate(number: float, frame_rate: float = 30):
|
||||||
"""
|
"""
|
||||||
this function calculates a factor that will be multiplied with the
|
this function calculates a factor that will be multiplied with the
|
||||||
physics of the game to provide a constant speed
|
physics of the game to provide a constant speed
|
||||||
|
:param frame_rate: the frame rate of the game
|
||||||
:param number: The number to scale by the factor
|
:param number: The number to scale by the factor
|
||||||
:return: The scaled number
|
:return: The scaled number
|
||||||
"""
|
"""
|
||||||
return number / (frame_rate / 30)
|
return number / (frame_rate / 30)
|
||||||
|
|
||||||
|
|
||||||
if what_to_run == 'menu':
|
class MainLoop:
|
||||||
screen_transform = PositionScale((0, 0), (1.5, 1.5))
|
def __init__(self):
|
||||||
|
self.GAME_STATE_MENU = 'main_menu'
|
||||||
|
self.GAME_STATE_LEVEL_SELECTION = 'level_selection'
|
||||||
|
self.GAME_STATE_LEVEL = 'level'
|
||||||
|
|
||||||
screen_height = 12 * 40 * 1.5
|
self.screen_transform: PositionScale = PositionScale((0, 0), (1.5, 1.5))
|
||||||
screen_width = 12 * 71 * 1.5
|
self.window_size: tuple[float, float] = (1, 1)
|
||||||
|
|
||||||
pygame.init()
|
pygame.init()
|
||||||
screen = pygame.display.set_mode((screen_width, screen_height))
|
|
||||||
pygame.display.set_caption("PM GAME")
|
pygame.display.set_caption("PM GAME")
|
||||||
clock = pygame.time.Clock()
|
|
||||||
frame_rate = 30
|
|
||||||
|
|
||||||
spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json")
|
self.update_position_scale(self.screen_transform)
|
||||||
sprite_manager = SpriteManager()
|
|
||||||
key_manager = KeyManager()
|
|
||||||
|
|
||||||
parsed_levels_manager = LevelManager('data/levels')
|
self.screen = self.screen
|
||||||
parsed_levels_manager.load_from_config('data/levels/levels.json')
|
self.clock = pygame.time.Clock()
|
||||||
|
self.frame_rate = 30
|
||||||
|
|
||||||
generated_level = LoadedLevel(sprite_manager, spritesheet_manager)
|
self.spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json")
|
||||||
|
self.sprite_manager = SpriteManager()
|
||||||
|
self.key_manager = KeyManager()
|
||||||
|
|
||||||
level_menu_width = screen_width / 2
|
self.parsed_levels_manager = LevelManager('data/levels')
|
||||||
level_menu_height = screen_height / 2
|
self.parsed_levels_manager.load_from_config('data/levels/levels.json')
|
||||||
level_menu = LevelMenu(parsed_levels_manager.levels, 0, 0, level_menu_width, level_menu_height, 3)
|
|
||||||
show_menu = False
|
|
||||||
|
|
||||||
|
self.screen_manager: Optional[ScreenManager] = None
|
||||||
|
self.game_state = self.GAME_STATE_MENU
|
||||||
|
self.set_game_state(self.GAME_STATE_LEVEL_SELECTION)
|
||||||
|
|
||||||
def load_next_level(selected_level):
|
def update_position_scale(self, position_scale: PositionScale):
|
||||||
global show_menu
|
self.screen_transform = position_scale
|
||||||
generated_level.destroy_level()
|
self.window_size = (
|
||||||
generated_level.load_level(selected_level)
|
self.screen_transform.scale[0] * ConstantsParser.CONFIG.block_size[0] *
|
||||||
destroy_menu()
|
ConstantsParser.CONFIG.level_size[0],
|
||||||
show_menu = False
|
self.screen_transform.scale[1] * ConstantsParser.CONFIG.block_size[1] *
|
||||||
|
ConstantsParser.CONFIG.level_size[1]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.screen = pygame.display.set_mode((self.window_size[0], self.window_size[1]))
|
||||||
|
|
||||||
def destroy_menu():
|
def select_level(self, level: Level):
|
||||||
global level_text_label
|
print(level.name)
|
||||||
for level_text_label in level_menu.level_text_labels:
|
self.set_game_state(self.GAME_STATE_LEVEL)
|
||||||
sprite_manager.remove_ui_element(level_text_label)
|
|
||||||
sprite_manager.remove_ui_element(level_menu.background)
|
|
||||||
|
|
||||||
|
def set_game_state(self, game_state: str):
|
||||||
|
self.game_state = game_state
|
||||||
|
|
||||||
level_menu.level_select_listener = lambda selected_level: load_next_level(selected_level)
|
if self.screen_manager is not None:
|
||||||
|
self.screen_manager.destroy()
|
||||||
|
|
||||||
|
if self.game_state == self.GAME_STATE_MENU:
|
||||||
|
self.screen_manager = MainMenuScreenManager(
|
||||||
|
self.sprite_manager, self.spritesheet_manager, self
|
||||||
|
)
|
||||||
|
elif self.game_state == self.GAME_STATE_LEVEL:
|
||||||
|
self.screen_manager = LevelScreenManager(
|
||||||
|
self.sprite_manager, self.spritesheet_manager, self
|
||||||
|
)
|
||||||
|
elif self.game_state == self.GAME_STATE_LEVEL_SELECTION:
|
||||||
|
self.screen_manager = LevelSelectionScreenManager(
|
||||||
|
self.sprite_manager, self.spritesheet_manager, self, self.parsed_levels_manager
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print('Invalid game state', self.game_state)
|
||||||
|
|
||||||
|
if self.screen_manager is not None:
|
||||||
|
self.screen_manager.initialize()
|
||||||
|
|
||||||
|
def main_loop(self):
|
||||||
while True:
|
while True:
|
||||||
clock.tick(frame_rate)
|
self.clock.tick(self.frame_rate)
|
||||||
|
|
||||||
pygame_events: list[pygame.event.Event] = pygame.event.get()
|
pygame_events: list[pygame.event.Event] = pygame.event.get()
|
||||||
key_manager.update_key_events(pygame_events)
|
self.key_manager.update_key_events(pygame_events)
|
||||||
click_events: list[ClickEvent] = ClickEvent.create_events(pygame_events, screen_transform)
|
click_events: list[ClickEvent] = ClickEvent.create_events(pygame_events, self.screen_transform)
|
||||||
|
|
||||||
for event in click_events:
|
for event in click_events:
|
||||||
for layer in sprite_manager.layers:
|
for layer in self.sprite_manager.layers:
|
||||||
for sprite in sprite_manager.layers[layer]:
|
for sprite in self.sprite_manager.layers[layer]:
|
||||||
if sprite.get_bounding_box().contains_point(event.world_position):
|
if sprite.get_bounding_box().contains_point(event.world_position):
|
||||||
sprite.click(event)
|
sprite.click(event)
|
||||||
|
|
||||||
|
@ -100,122 +128,19 @@ if what_to_run == 'menu':
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
quit()
|
quit()
|
||||||
if key_manager.is_keymap_down(KeyManager.KEY_ESCAPE):
|
|
||||||
if show_menu:
|
|
||||||
show_menu = False
|
|
||||||
destroy_menu()
|
|
||||||
else:
|
|
||||||
show_menu = True
|
|
||||||
sprite_manager.add_ui_element(DrawLayers.UI, level_menu.background)
|
|
||||||
for level_text_label in level_menu.level_text_labels:
|
|
||||||
sprite_manager.add_ui_element(DrawLayers.UI, level_text_label)
|
|
||||||
|
|
||||||
screen.fill((0, 0, 0))
|
self.screen.fill((0, 0, 0))
|
||||||
sprite_manager.tick(TickData(apply_frame_rate(1), pygame_events, key_manager, click_events, screen_transform))
|
self.sprite_manager.tick(
|
||||||
sprite_manager.draw(screen, screen_transform)
|
TickData(apply_frame_rate(1, self.frame_rate),
|
||||||
|
pygame_events,
|
||||||
|
self.key_manager,
|
||||||
|
click_events,
|
||||||
|
self.screen_transform)
|
||||||
|
)
|
||||||
|
self.sprite_manager.draw(self.screen, self.screen_transform)
|
||||||
|
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
|
|
||||||
elif what_to_run == 'level':
|
|
||||||
screen_transform = PositionScale((0, 0), (1.5, 1.5))
|
|
||||||
|
|
||||||
pygame.init()
|
main_loop: MainLoop = MainLoop()
|
||||||
screen = pygame.display.set_mode((12 * ConstantsParser.CONFIG.level_size[0] * screen_transform.scale[0],
|
main_loop.main_loop()
|
||||||
12 * ConstantsParser.CONFIG.level_size[1] * screen_transform.scale[1]),
|
|
||||||
flags=pygame.HWSURFACE | pygame.DOUBLEBUF,
|
|
||||||
vsync=1,
|
|
||||||
depth=1)
|
|
||||||
|
|
||||||
pygame.display.set_caption("PM GAME")
|
|
||||||
clock = pygame.time.Clock()
|
|
||||||
frame_rate = 30
|
|
||||||
|
|
||||||
spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json")
|
|
||||||
sprite_manager = SpriteManager()
|
|
||||||
key_manager = KeyManager()
|
|
||||||
|
|
||||||
parsed_levels_manager = LevelManager('data/levels')
|
|
||||||
parsed_levels_manager.load_from_config('data/levels/levels.json')
|
|
||||||
|
|
||||||
generated_level = LoadedLevel(sprite_manager, spritesheet_manager)
|
|
||||||
generated_level.load_level(parsed_levels_manager.levels[1])
|
|
||||||
ghost_character = PlayerSprite(spritesheet_manager.get_sheet("ghost_character"))
|
|
||||||
ghost_character.position_scale = PositionScale((90, 50), (1, 1))
|
|
||||||
sprite_manager.add_ui_element(DrawLayers.OBJECTS, ghost_character)
|
|
||||||
|
|
||||||
calculated_frame_rate_text = TextLabel("0 FPS", 2, 2, 70, alignment="left")
|
|
||||||
calculated_frame_rate_text.position_scale.scale = (0.3, 0.3)
|
|
||||||
sprite_manager.add_ui_element(DrawLayers.UI, calculated_frame_rate_text)
|
|
||||||
|
|
||||||
left_sprite = None
|
|
||||||
right_sprite = None
|
|
||||||
|
|
||||||
while True:
|
|
||||||
clock.tick(frame_rate)
|
|
||||||
|
|
||||||
calculated_frame_rate_text.text = f"{round(clock.get_fps())} FPS"
|
|
||||||
|
|
||||||
pygame_events: list[pygame.event.Event] = pygame.event.get()
|
|
||||||
key_manager.update_key_events(pygame_events)
|
|
||||||
click_events: list[ClickEvent] = ClickEvent.create_events(pygame_events, screen_transform)
|
|
||||||
|
|
||||||
for event in pygame_events:
|
|
||||||
if event.type == pygame.QUIT:
|
|
||||||
pygame.quit()
|
|
||||||
quit()
|
|
||||||
|
|
||||||
for event in click_events:
|
|
||||||
for layer in sprite_manager.layers:
|
|
||||||
for sprite in sprite_manager.layers[layer]:
|
|
||||||
if sprite.get_bounding_box().contains_point(event.world_position):
|
|
||||||
if event.is_click_down(ClickEvent.CLICK_LEFT):
|
|
||||||
left_sprite = sprite
|
|
||||||
if event.is_click_down(ClickEvent.CLICK_RIGHT):
|
|
||||||
right_sprite = sprite
|
|
||||||
|
|
||||||
if left_sprite is not None and right_sprite is not None:
|
|
||||||
print(left_sprite.get_bounding_box().distance(right_sprite.get_bounding_box()))
|
|
||||||
left_sprite = None
|
|
||||||
right_sprite = None
|
|
||||||
|
|
||||||
screen.fill((0, 0, 0))
|
|
||||||
# Playground to test background on any level
|
|
||||||
screen.blit(test_background_castle, (0, 0))
|
|
||||||
|
|
||||||
sprite_manager.tick(TickData(apply_frame_rate(1), pygame_events, key_manager, click_events, screen_transform))
|
|
||||||
sprite_manager.draw(screen, screen_transform)
|
|
||||||
pygame.display.update()
|
|
||||||
|
|
||||||
|
|
||||||
elif what_to_run == 'textlabel':
|
|
||||||
screen_transform = PositionScale((0, 0), (4, 4))
|
|
||||||
|
|
||||||
pygame.init()
|
|
||||||
screen = pygame.display.set_mode((800, 800))
|
|
||||||
pygame.display.set_caption("PM GAME")
|
|
||||||
clock = pygame.time.Clock()
|
|
||||||
|
|
||||||
test1 = TextLabel("Das ist ein Test", 100, 0, 50, alignment="left")
|
|
||||||
test2 = TextLabel("Das ist ein Test", 100, 50, 50, alignment="left")
|
|
||||||
test3 = TextLabel("Das ist ein Test", 100, 20, 50, alignment="left")
|
|
||||||
|
|
||||||
test1.position_scale.scale = (0.2, 0.2)
|
|
||||||
test2.position_scale.scale = (0.4, 0.4)
|
|
||||||
test3.position_scale.scale = (0.2, 0.2)
|
|
||||||
|
|
||||||
test3.visible = False
|
|
||||||
|
|
||||||
while True:
|
|
||||||
clock.tick(5)
|
|
||||||
|
|
||||||
for event in pygame.event.get():
|
|
||||||
if event.type == pygame.QUIT:
|
|
||||||
pygame.quit()
|
|
||||||
|
|
||||||
screen.fill((0, 0, 110))
|
|
||||||
|
|
||||||
test1.draw(screen, screen_transform)
|
|
||||||
test2.draw(screen, screen_transform)
|
|
||||||
test3.draw(screen, screen_transform)
|
|
||||||
|
|
||||||
pygame.display.update()
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
|
||||||
class BoundingBox:
|
class BoundingBox:
|
||||||
def __init__(self, x, y, width, height):
|
def __init__(self, x, y, width, height):
|
||||||
|
@ -46,3 +48,6 @@ class BoundingBox:
|
||||||
"""
|
"""
|
||||||
return self.x < bounding_box.x + bounding_box.width and self.x + self.width > bounding_box.x and \
|
return self.x < bounding_box.x + bounding_box.width and self.x + self.width > bounding_box.x and \
|
||||||
self.y < bounding_box.y + bounding_box.height and self.y + self.height > bounding_box.y
|
self.y < bounding_box.y + bounding_box.height and self.y + self.height > bounding_box.y
|
||||||
|
|
||||||
|
def get_rect(self) -> pygame.Rect:
|
||||||
|
return pygame.Rect(self.x, self.y, self.width, self.height)
|
||||||
|
|
|
@ -8,24 +8,26 @@ from sprite.BoundingBox import BoundingBox
|
||||||
from ui_elements.UiElement import UiElement
|
from ui_elements.UiElement import UiElement
|
||||||
|
|
||||||
|
|
||||||
class Background(UiElement):
|
class ColoredRectangleUiElement(UiElement):
|
||||||
|
|
||||||
def __init__(self, x_pos: float, y_pos: float, width: float, height: float, color: tuple):
|
def __init__(self, width: float, height: float, color: tuple):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.x_pos = x_pos
|
|
||||||
self.y_pos = y_pos
|
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.color = color
|
self.color = color
|
||||||
|
|
||||||
def tick(self, tick_data: TickData):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def render_sprite_image(self) -> Optional[Surface]:
|
def render_sprite_image(self) -> Optional[Surface]:
|
||||||
|
bounding_box = self.get_bounding_box()
|
||||||
|
background_rect = bounding_box.get_rect()
|
||||||
|
|
||||||
surface = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
|
surface = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
|
||||||
background_rect = pygame.Rect(self.x_pos, self.y_pos, self.width, self.height)
|
|
||||||
pygame.draw.rect(surface, self.color, background_rect)
|
pygame.draw.rect(surface, self.color, background_rect)
|
||||||
return surface
|
return surface
|
||||||
|
|
||||||
def get_bounding_box(self) -> BoundingBox:
|
def get_bounding_box(self) -> BoundingBox:
|
||||||
return BoundingBox(-1, -1, 0, 0)
|
return BoundingBox(self.position_scale.position[0], self.position_scale.position[1],
|
||||||
|
self.width, self.height)
|
||||||
|
|
||||||
|
def tick(self, tick_data: TickData):
|
||||||
|
pass
|
Loading…
Reference in New Issue