sep-pm-platformer/project/level/elements/LoadedLevel.py

155 lines
6.5 KiB
Python
Raw Normal View History

from typing import Optional
2023-03-26 11:21:22 +02:00
from level.Level import Level
2023-03-27 18:52:49 +02:00
from level.elements.dynamic.BouncingBallLevelElement import BouncingBallLevelElement
from level.elements.dynamic.PushableBoxLevelElement import PushableBoxLevelElement
2023-03-29 16:41:35 +02:00
from level.elements.static.InvisibleElement import InvisibleElement
2023-03-29 15:19:37 +02:00
from level.elements.static.VacuumCleanerElement import VacuumCleanerElement
2023-03-28 18:09:29 +02:00
from level.elements.static.GoalDoorReceiverLevelElement import GoalDoorReceiverLevelElement
2023-03-28 17:26:47 +02:00
from level.elements.static.SpikeLevelElement import SpikeLevelElement
from level.elements.static.ButtonInputLevelElement import ButtonInputLevelElement
from level.elements.static.GateReceiverLevelElement import GateReceiverLevelElement
from level.elements.LevelElement import LevelElement
from level.elements.static.LeverInputLevelElement import LeverInputLevelElement
from level.elements.static.SimpleBlockLevelElement import SimpleBlockLevelElement
from level.elements.static.UnknownTileLevelElement import UnknownTileLevelElement
2023-03-27 11:46:03 +02:00
from physics import ConstantsParser
2023-03-26 11:21:22 +02:00
from physics.SpriteManager import SpriteManager, DrawLayers
2023-03-29 13:50:48 +02:00
from physics.sprites.PlayerSprite import PlayerSprite
from sprite.PositionScale import PositionScale
2023-03-26 11:21:22 +02:00
from sprite.SpritesheetManager import SpritesheetManager
2023-03-27 11:46:03 +02:00
TILES = {
'#': SimpleBlockLevelElement,
'+': SimpleBlockLevelElement,
'-': SimpleBlockLevelElement,
'l': SimpleBlockLevelElement,
'r': SimpleBlockLevelElement,
'~': SimpleBlockLevelElement,
'|': SimpleBlockLevelElement,
2023-03-27 12:51:44 +02:00
'P': ButtonInputLevelElement,
2023-03-27 14:38:52 +02:00
'L': LeverInputLevelElement,
'G': GateReceiverLevelElement,
2023-03-28 18:09:29 +02:00
'D': GoalDoorReceiverLevelElement,
'M': PushableBoxLevelElement,
2023-03-27 18:52:49 +02:00
'q': BouncingBallLevelElement,
2023-03-28 17:26:47 +02:00
'S': SpikeLevelElement,
's': SpikeLevelElement,
'<': SpikeLevelElement,
2023-03-29 15:19:37 +02:00
'>': SpikeLevelElement,
2023-03-29 16:41:35 +02:00
'A': VacuumCleanerElement,
'i': InvisibleElement
2023-03-27 11:46:03 +02:00
}
2023-03-26 15:14:06 +02:00
2023-03-29 17:12:31 +02:00
BACK_LAYER = [
]
FRONT_LAYER = [
'M'
]
2023-03-26 15:14:06 +02:00
2023-03-26 11:21:22 +02:00
class LoadedLevel:
def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager):
self.sprite_manager = sprite_manager
self.spritesheet_manager = spritesheet_manager
self.blocks = []
self.elements_by_id: dict[str, LevelElement] = {}
self.level_screen_manager = None
2023-03-26 11:21:22 +02:00
def load_level(self, level: Level):
2023-03-29 17:12:31 +02:00
# create a wall of InvisibleElement around the level left and right
# block_left = SimpleBlockLevelElement({'name': '#', 'position': (30, 300)}, self, self.level_screen_manager)
# block_left.load(self.sprite_manager, self.spritesheet_manager, level)
# self.blocks.append(block_left)
# self.sprite_manager.add_ui_element(DrawLayers.OBJECTS_BACK, block_left)
for i in range(0, 100):
block_left = InvisibleElement({'name': 'i', 'position': (-16, i * 32)}, self, self.level_screen_manager)
block_left.load(self.sprite_manager, self.spritesheet_manager, level)
self.blocks.append(block_left)
self.sprite_manager.add_ui_element(DrawLayers.OBJECTS_BACK, block_left)
for i in range(0, 100):
block_right = InvisibleElement({'name': 'i', 'position':
(ConstantsParser.CONFIG.block_size[0] * ConstantsParser.CONFIG.level_size[0] + 4, i * 32)},
self, self.level_screen_manager)
block_right.load(self.sprite_manager, self.spritesheet_manager, level)
self.blocks.append(block_right)
self.sprite_manager.add_ui_element(DrawLayers.OBJECTS_BACK, block_right)
for row_number, row in enumerate(level.tiles):
for tile_number, tile in enumerate(row):
2023-03-27 13:08:22 +02:00
world_position = (tile_number, row_number)
2023-03-27 11:46:03 +02:00
position = (tile_number * ConstantsParser.CONFIG.block_size[0],
row_number * ConstantsParser.CONFIG.block_size[1])
2023-03-27 13:08:22 +02:00
tile['world_position'] = world_position
2023-03-27 11:46:03 +02:00
tile['position'] = position
name = tile['name']
element = None
2023-03-29 14:01:55 +02:00
layer = DrawLayers.OBJECTS
2023-03-27 11:46:03 +02:00
if name in TILES:
element = TILES[name](tile, self, self.level_screen_manager)
2023-03-29 17:12:31 +02:00
if name in BACK_LAYER:
layer = DrawLayers.OBJECTS_BACK
elif name in FRONT_LAYER:
layer = DrawLayers.OBJECTS_FRONT
2023-03-29 13:50:48 +02:00
elif name == 'C':
ghost_character = PlayerSprite(self.spritesheet_manager.get_sheet("ghost_character"))
ghost_character.position_scale = PositionScale((position[0], position[1]), (1, 1))
2023-03-29 14:01:55 +02:00
layer = DrawLayers.PLAYER
self.blocks.append(ghost_character)
self.sprite_manager.add_ui_element(layer, ghost_character)
2023-03-29 13:50:48 +02:00
elif not name == '':
print(f"Unknown tile at {position}: {name}")
2023-03-29 16:44:25 +02:00
element = UnknownTileLevelElement(tile, self, self.level_screen_manager)
if element:
2023-03-27 11:46:03 +02:00
self.blocks.append(element)
2023-03-29 14:01:55 +02:00
self.sprite_manager.add_ui_element(layer, element)
2023-03-27 11:46:03 +02:00
element.load(self.sprite_manager, self.spritesheet_manager, level)
self.elements_by_id[element.id] = element
2023-03-27 11:46:03 +02:00
2023-03-27 13:08:22 +02:00
if isinstance(element, SimpleBlockLevelElement):
if self.is_surrounded_by_blocks(world_position, level.tiles):
element.is_collider = False
2023-03-27 15:17:01 +02:00
element.register_collisions = False
# self.sprite_manager.remove_ui_element(element)
2023-03-27 13:08:22 +02:00
def get_element_by_id(self, search_id: str) -> Optional[LevelElement]:
if search_id in self.elements_by_id:
return self.elements_by_id[search_id]
return None
2023-03-27 13:08:22 +02:00
def is_surrounded_by_blocks(self, position, tiles):
for i in range(-1, 2):
for j in range(-1, 2):
if i == 0 and j == 0:
continue
if position[0] + i < 0 or position[0] + i >= len(tiles[0]):
continue
if position[1] + j < 0 or position[1] + j >= len(tiles):
continue
tile = tiles[position[1] + j][position[0] + i]
if not tile['name'] in ['#', '+', '-', 'l', 'r', '~', '|']:
return False
return True
def destroy_level(self):
2023-03-26 15:14:06 +02:00
for block in self.blocks:
self.sprite_manager.remove_ui_element(block)
del self.blocks
2023-03-28 18:09:29 +02:00
self.blocks = []