2023-03-27 16:07:42 +02:00
|
|
|
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
|
2023-03-27 18:37:30 +02:00
|
|
|
from level.elements.dynamic.PushableBoxLevelElement import PushableBoxLevelElement
|
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
|
2023-03-27 18:37:30 +02:00
|
|
|
from level.elements.static.ButtonInputLevelElement import ButtonInputLevelElement
|
|
|
|
from level.elements.static.GateReceiverLevelElement import GateReceiverLevelElement
|
2023-03-27 16:07:42 +02:00
|
|
|
from level.elements.LevelElement import LevelElement
|
2023-03-27 18:37:30 +02:00
|
|
|
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
|
|
|
|
from sprite.SpritesheetManager import SpritesheetManager
|
|
|
|
|
2023-03-27 11:46:03 +02:00
|
|
|
TILES = {
|
|
|
|
'#': SimpleBlockLevelElement,
|
2023-03-27 12:15:35 +02:00
|
|
|
'+': 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,
|
2023-03-27 16:07:42 +02:00
|
|
|
|
|
|
|
'G': GateReceiverLevelElement,
|
2023-03-27 18:37:30 +02:00
|
|
|
|
2023-03-28 18:09:29 +02:00
|
|
|
'D': GoalDoorReceiverLevelElement,
|
|
|
|
|
2023-03-27 18:37:30 +02:00
|
|
|
'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,
|
|
|
|
'>': SpikeLevelElement
|
2023-03-27 11:46:03 +02:00
|
|
|
}
|
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
|
2023-03-26 14:12:46 +02:00
|
|
|
self.blocks = []
|
2023-03-27 16:07:42 +02:00
|
|
|
self.elements_by_id: dict[str, LevelElement] = {}
|
2023-03-26 11:21:22 +02:00
|
|
|
|
|
|
|
def load_level(self, level: Level):
|
2023-03-26 14:12:46 +02:00
|
|
|
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']
|
2023-03-27 12:15:35 +02:00
|
|
|
|
|
|
|
element = None
|
|
|
|
|
2023-03-27 11:46:03 +02:00
|
|
|
if name in TILES:
|
|
|
|
element = TILES[name](tile, self)
|
2023-03-27 12:15:35 +02:00
|
|
|
elif not name == '':
|
|
|
|
print(f"Unknown tile at {position}: {name}")
|
|
|
|
element = UnknownTileLevelElement(tile, self)
|
|
|
|
|
|
|
|
if element:
|
2023-03-27 11:46:03 +02:00
|
|
|
self.blocks.append(element)
|
|
|
|
self.sprite_manager.add_ui_element(DrawLayers.OBJECTS, element)
|
|
|
|
element.load(self.sprite_manager, self.spritesheet_manager, level)
|
2023-03-27 16:07:42 +02:00
|
|
|
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
|
|
|
|
2023-03-27 16:07:42 +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
|
|
|
|
|
2023-03-26 14:12:46 +02:00
|
|
|
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 = []
|