sep-pm-platformer/project/main.py

222 lines
8.1 KiB
Python

import random
import pygame
from level.LevelManager import LevelManager
from level.elements.LoadedLevel import LoadedLevel
from physics import ConstantsParser
from physics.SpriteManager import SpriteManager, DrawLayers
from physics.TickData import TickData
from physics.sprites.PlayerSprite import PlayerSprite
from sprite.PositionScale import PositionScale
from sprite.Sprite import Sprite
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.LevelMenu import LevelMenu
from ui_elements.TextLabel import TextLabel
what_to_run = 'level'
WIDTH = 12 * 71 * 1.5
HEIGHT = 12 * 40 * 1.5
# Background to test for level design
test_background_castle = pygame.transform.scale(pygame.image.load('data/sprites/castle_bg.png'), (WIDTH, HEIGHT))
# test_background_cave = pygame.transform.scale(pygame.image.load('data/sprites/cave_bg.png'), (WIDTH, HEIGHT))
#test_background_tutorial = pygame.transform.scale(pygame.image.load('data/sprites/tutorial_bg.png'), (WIDTH, HEIGHT))
def apply_frame_rate(number: float):
"""
this function calculates a factor that will be multiplied with the
physics of the game to provide a constant speed
:param number: The number to scale by the factor
:return: The scaled number
"""
return number / (frame_rate / 30)
if what_to_run == 'menu':
screen_transform = PositionScale((0, 0), (1.5, 1.5))
screen_height = 12 * 40 * 1.5
screen_width = 12 * 71 * 1.5
pygame.init()
screen = pygame.display.set_mode((screen_width, screen_height))
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)
level_menu_width = screen_width / 2
level_menu_height = screen_height / 2
level_menu = LevelMenu(parsed_levels_manager.levels, 0, 0, level_menu_width, level_menu_height, 3)
show_menu = False
def load_next_level(selected_level):
global show_menu
generated_level.destroy_level()
generated_level.load_level(selected_level)
destroy_menu()
show_menu = False
def destroy_menu():
global level_text_label
for level_text_label in level_menu.level_text_labels:
sprite_manager.remove_ui_element(level_text_label)
sprite_manager.remove_ui_element(level_menu.background)
level_menu.level_select_listener = lambda selected_level: load_next_level(selected_level)
while True:
clock.tick(frame_rate)
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 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):
sprite.click(event)
for event in pygame_events:
if event.type == pygame.QUIT:
pygame.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))
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 == 'level':
screen_transform = PositionScale((0, 0), (1.5, 1.5))
pygame.init()
screen = pygame.display.set_mode((12 * ConstantsParser.CONFIG.level_size[0] * screen_transform.scale[0],
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[9])
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()