parent
6147541a9e
commit
85a34b01d8
|
@ -20,7 +20,7 @@
|
|||
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
|
||||
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,+,+,+,+,+,+,#,#,#,#,#,#,#,#,#,,,,,,,
|
||||
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,
|
||||
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
|
||||
,,,,,M,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
|
||||
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
|
||||
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,+,+,+,+,+,+,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
|
||||
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
|
||||
|
@ -31,14 +31,16 @@
|
|||
,,,,,,,,,,,,,,,,,,,,,,,#,#,,,,,,,,,,,+,+,+,+,+,+,,,,,#,#,#,#,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,G,,,,,,,,,,,D,,,
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,L,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,,,,,,,P,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
,,,,,,,,,,P,,,,,,P,,,,,,,,,M,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,#,#,#,#,#,#,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,#,#,#,#,#,+,+,+,+,+,+,+,+,+,+
|
||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
|
||||
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
AQ,18,requires_xor=lever-1;button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
AU,32,requires_and=lever-1;button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
AJ,33,id=lever-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
Q,34,id=button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
F,23,size=7,,weight=0.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
|
Binary file not shown.
After Width: | Height: | Size: 536 B |
|
@ -340,6 +340,19 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "movable_box",
|
||||
"subsheets": [
|
||||
{
|
||||
"id": "1",
|
||||
"delays": [
|
||||
1
|
||||
],
|
||||
"width": 12,
|
||||
"height": 12
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "test_1",
|
||||
"subsheets": [
|
||||
|
|
|
@ -34,7 +34,7 @@ class Level:
|
|||
continue
|
||||
|
||||
split_item = line[i].split('=')
|
||||
if split_item[0] in ['id', 'emitter_state', 'debug', 'active_state']:
|
||||
if split_item[0] in ['id', 'emitter_state', 'debug', 'active_state', 'size', 'weight']:
|
||||
tile[split_item[0]] = split_item[1]
|
||||
elif split_item[0] in ['requires', 'requires_and', 'requires_or', 'requires_xor']:
|
||||
tile[split_item[0]] = split_item[1].split(';')
|
||||
|
|
|
@ -10,7 +10,6 @@ class LevelElement:
|
|||
def __init__(self, tile: dict, loaded_level):
|
||||
self.tile = tile
|
||||
self.loaded_level = loaded_level
|
||||
self.sprites = []
|
||||
|
||||
if 'id' in tile:
|
||||
self.id = tile['id']
|
||||
|
@ -20,7 +19,3 @@ class LevelElement:
|
|||
@abstractmethod
|
||||
def load(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, level: Level):
|
||||
pass
|
||||
|
||||
def destroy(self, sprite_manager: SpriteManager):
|
||||
for sprite in self.sprites:
|
||||
sprite_manager.remove_ui_element(sprite)
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
from typing import Optional
|
||||
|
||||
from level.Level import Level
|
||||
from level.elements.ButtonInputLevelElement import ButtonInputLevelElement
|
||||
from level.elements.GateReceiverLevelElement import GateReceiverLevelElement
|
||||
from level.elements.dynamic.PushableBoxLevelElement import PushableBoxLevelElement
|
||||
from level.elements.static.ButtonInputLevelElement import ButtonInputLevelElement
|
||||
from level.elements.static.GateReceiverLevelElement import GateReceiverLevelElement
|
||||
from level.elements.LevelElement import LevelElement
|
||||
from level.elements.LeverInputLevelElement import LeverInputLevelElement
|
||||
from level.elements.SimpleBlockLevelElement import SimpleBlockLevelElement
|
||||
from level.elements.UnknownTileLevelElement import UnknownTileLevelElement
|
||||
from level.elements.static.LeverInputLevelElement import LeverInputLevelElement
|
||||
from level.elements.static.SimpleBlockLevelElement import SimpleBlockLevelElement
|
||||
from level.elements.static.UnknownTileLevelElement import UnknownTileLevelElement
|
||||
from physics import ConstantsParser
|
||||
from physics.SpriteManager import SpriteManager, DrawLayers
|
||||
from sprite.SpritesheetManager import SpritesheetManager
|
||||
|
@ -24,6 +25,8 @@ TILES = {
|
|||
'L': LeverInputLevelElement,
|
||||
|
||||
'G': GateReceiverLevelElement,
|
||||
|
||||
'M': PushableBoxLevelElement,
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,8 +51,6 @@ class LoadedLevel:
|
|||
|
||||
if name in TILES:
|
||||
element = TILES[name](tile, self)
|
||||
if isinstance(element, LeverInputLevelElement):
|
||||
print(f"Found lever at {position}")
|
||||
elif not name == '':
|
||||
print(f"Unknown tile at {position}: {name}")
|
||||
element = UnknownTileLevelElement(tile, self)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
from abc import ABC
|
||||
|
||||
from level.elements.LevelElement import LevelElement
|
||||
from sprite.DynamicSprite import DynamicSprite
|
||||
|
||||
|
||||
class DynamicLevelElement(DynamicSprite, LevelElement, ABC):
|
||||
def __init__(self, tile: dict, loaded_level):
|
||||
DynamicSprite.__init__(self)
|
||||
LevelElement.__init__(self, tile, loaded_level)
|
|
@ -0,0 +1,18 @@
|
|||
from level.Level import Level
|
||||
from level.elements.dynamic.PushableLevelElement import PushableLevelElement
|
||||
from physics.SpriteManager import SpriteManager
|
||||
from sprite.SpritesheetManager import SpritesheetManager
|
||||
|
||||
|
||||
class PushableBoxLevelElement(PushableLevelElement):
|
||||
def __init__(self, tile: dict, loaded_level):
|
||||
super().__init__(tile, loaded_level)
|
||||
|
||||
if 'size' in self.tile:
|
||||
self.position_scale.scale = (float(self.tile['size']),
|
||||
float(self.tile['size']))
|
||||
|
||||
def load(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, level: Level):
|
||||
self.spritesheet = spritesheet_manager.get_sheet('movable_box')
|
||||
self.set_animation_state('1')
|
||||
self.position_scale.position = self.tile['position']
|
|
@ -0,0 +1,28 @@
|
|||
from abc import ABC
|
||||
|
||||
from level.elements.dynamic.DynamicLevelElement import DynamicLevelElement
|
||||
from physics.CollisionDirection import CollisionDirection
|
||||
from physics.TickData import TickData
|
||||
|
||||
|
||||
class PushableLevelElement(DynamicLevelElement, ABC):
|
||||
def __init__(self, tile: dict, loaded_level):
|
||||
super().__init__(tile, loaded_level)
|
||||
|
||||
if 'weight' in self.tile:
|
||||
self.weight = float(self.tile['weight'])
|
||||
else:
|
||||
self.weight = 1.0
|
||||
|
||||
def tick(self, tick_data: TickData):
|
||||
super().tick(tick_data)
|
||||
|
||||
collides_element = self.get_collides_with_direction(CollisionDirection.LEFT)
|
||||
|
||||
if collides_element:
|
||||
self.motion = (self.motion[0] + self.weight, self.motion[1])
|
||||
|
||||
collides_element = self.get_collides_with_direction(CollisionDirection.RIGHT)
|
||||
|
||||
if collides_element:
|
||||
self.motion = (self.motion[0] - self.weight, self.motion[1])
|
|
@ -1,5 +1,5 @@
|
|||
from level.Level import Level
|
||||
from level.elements.InputLevelElement import InputLevelElement
|
||||
from level.elements.static.InputLevelElement import InputLevelElement
|
||||
from physics.CollisionDirection import CollisionDirection
|
||||
from physics.SpriteManager import SpriteManager
|
||||
from physics.TickData import TickData
|
|
@ -1,5 +1,5 @@
|
|||
from level.Level import Level
|
||||
from level.elements.ReceiverLevelElement import ReceiverLevelElement
|
||||
from level.elements.static.ReceiverLevelElement import ReceiverLevelElement
|
||||
from physics.SpriteManager import SpriteManager
|
||||
from sprite.SpritesheetManager import SpritesheetManager
|
||||
|
||||
|
@ -13,7 +13,6 @@ class GateReceiverLevelElement(ReceiverLevelElement):
|
|||
self.set_animation_state('open' if self.active_state else 'close')
|
||||
self.position_scale.position = self.tile['position']
|
||||
|
||||
|
||||
def set_active(self, active: bool):
|
||||
super().set_active(active)
|
||||
self.set_animation_state('open' if self.active_state else 'close')
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
from abc import ABC
|
||||
|
||||
from level.elements.StaticLevelElement import StaticLevelElement
|
||||
from level.elements.static.StaticLevelElement import StaticLevelElement
|
||||
|
||||
|
||||
class InputLevelElement(StaticLevelElement, ABC):
|
|
@ -1,5 +1,5 @@
|
|||
from level.Level import Level
|
||||
from level.elements.InputLevelElement import InputLevelElement
|
||||
from level.elements.static.InputLevelElement import InputLevelElement
|
||||
from physics.CollisionDirection import CollisionDirection
|
||||
from physics.SpriteManager import SpriteManager
|
||||
from physics.TickData import TickData
|
|
@ -1,6 +1,6 @@
|
|||
from abc import ABC
|
||||
|
||||
from level.elements.StaticLevelElement import StaticLevelElement
|
||||
from level.elements.static.StaticLevelElement import StaticLevelElement
|
||||
from physics.TickData import TickData
|
||||
|
||||
|
||||
|
@ -18,13 +18,17 @@ class ReceiverLevelElement(StaticLevelElement, ABC):
|
|||
self.requires['xor'] = tile['requires_xor']
|
||||
|
||||
self.active_state = False
|
||||
|
||||
if 'active_state' in tile:
|
||||
self.set_active(tile['active_state'] == 'True')
|
||||
self.active_state_invert = tile['active_state'] == 'True'
|
||||
else:
|
||||
self.set_active(False)
|
||||
self.active_state_invert = False
|
||||
|
||||
def set_active(self, active: bool):
|
||||
self.active_state = active
|
||||
if self.active_state_invert:
|
||||
self.active_state = not active
|
||||
else:
|
||||
self.active_state = active
|
||||
|
||||
def tick(self, tick_data: TickData):
|
||||
super().tick(tick_data)
|
||||
|
@ -48,7 +52,6 @@ class ReceiverLevelElement(StaticLevelElement, ABC):
|
|||
break
|
||||
|
||||
if 'xor' in self.requires:
|
||||
print(self.requires['xor'])
|
||||
for requirement in self.requires['xor']:
|
||||
element = self.loaded_level.get_element_by_id(requirement)
|
||||
if element and element.emitter_state:
|
|
@ -1,7 +1,7 @@
|
|||
import random
|
||||
|
||||
from level.Level import Level
|
||||
from level.elements.StaticLevelElement import StaticLevelElement
|
||||
from level.elements.static.StaticLevelElement import StaticLevelElement
|
||||
from physics.SpriteManager import SpriteManager
|
||||
from sprite.SpritesheetManager import SpritesheetManager
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import uuid
|
||||
from abc import ABC
|
||||
|
||||
from level.elements.LevelElement import LevelElement
|
|
@ -1,5 +1,5 @@
|
|||
from level.Level import Level
|
||||
from level.elements.StaticLevelElement import StaticLevelElement
|
||||
from level.elements.static.StaticLevelElement import StaticLevelElement
|
||||
from physics.SpriteManager import SpriteManager
|
||||
from sprite.SpritesheetManager import SpritesheetManager
|
||||
|
|
@ -12,6 +12,7 @@ from sprite.PositionScale import PositionScale
|
|||
from sprite.SpritesheetManager import SpritesheetManager
|
||||
from sprite.Sprite import Sprite
|
||||
from sprite.StaticSprite import StaticSprite
|
||||
from ui_elements import CoordinateTransform
|
||||
from ui_elements.ClickEvent import ClickEvent
|
||||
from ui_elements.KeyManager import KeyManager
|
||||
from ui_elements.LevelMenu import LevelMenu
|
||||
|
@ -66,6 +67,12 @@ if what_to_run == 'menu':
|
|||
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.screen_position):
|
||||
sprite.click(event)
|
||||
|
||||
for event in pygame_events:
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
|
@ -97,7 +104,7 @@ elif what_to_run == 'level':
|
|||
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])
|
||||
generated_level.load_level(parsed_levels_manager.levels[0])
|
||||
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)
|
||||
|
|
|
@ -4,6 +4,7 @@ from typing import Optional
|
|||
from physics.CollisionDirection import CollisionDirection
|
||||
from physics.TickData import TickData
|
||||
from sprite.DynamicSprite import DynamicSprite
|
||||
from sprite.PositionScale import PositionScale
|
||||
from sprite.Sprite import Sprite
|
||||
from sprite.StaticSprite import StaticSprite
|
||||
from ui_elements.UiElement import UiElement
|
||||
|
@ -26,6 +27,8 @@ class PhysicsElementsHandler:
|
|||
sprites = []
|
||||
for layer in layers:
|
||||
for sprite in layers[layer]:
|
||||
# if str(type(sprite)) == "<class 'level.elements.dynamic.PushableBoxLevelElement.PushableBoxLevelElement'>":
|
||||
# print(f"Found pushable box")
|
||||
sprite.tick(tick_data)
|
||||
if isinstance(sprite, Sprite):
|
||||
sprites.append(sprite)
|
||||
|
@ -51,15 +54,15 @@ class PhysicsElementsHandler:
|
|||
sorted_dynamic_sprites = sorted(dynamic_sprites, key=lambda spr: spr.position_scale.position[1])
|
||||
|
||||
for sprite in sorted_dynamic_sprites:
|
||||
collides_with = self.attempt_move(tick_data.dt, sprite, colliders, MOTION_STEPS)
|
||||
collides_with = self.attempt_move(tick_data, sprite, colliders, MOTION_STEPS)
|
||||
if collides_with is not None:
|
||||
for callback in self.collision_callbacks:
|
||||
callback(sprite, collides_with)
|
||||
|
||||
def attempt_move(self, dt: float, sprite: DynamicSprite, colliders: list[StaticSprite],
|
||||
def attempt_move(self, tick_data: TickData, sprite: DynamicSprite, colliders: list[StaticSprite],
|
||||
motion_steps: int) -> Optional[StaticSprite]:
|
||||
total_motion = sprite.motion
|
||||
motion_step = ((total_motion[0] * dt) / motion_steps, (total_motion[1] * dt) / motion_steps)
|
||||
motion_step = ((total_motion[0] * tick_data.dt) / motion_steps, (total_motion[1] * tick_data.dt) / motion_steps)
|
||||
|
||||
collides_with_last = None
|
||||
collided = [False, False]
|
||||
|
@ -73,7 +76,7 @@ class PhysicsElementsHandler:
|
|||
|
||||
# print('Elements: ', list(filter(lambda spr: str(type(spr)) == "<class 'level.elements.LeverInputLevelElement.LeverInputLevelElement'>", colliders)))
|
||||
|
||||
collides_with = self.check_collides(sprite, colliders)
|
||||
collides_with = self.check_collides(sprite, colliders, tick_data.screen_transform)
|
||||
for collider in collides_with:
|
||||
if collider is not None:
|
||||
if sprite.is_collider and collider.is_collider:
|
||||
|
@ -117,7 +120,7 @@ class PhysicsElementsHandler:
|
|||
sprite.position_scale.position[1] + motion_step[1]
|
||||
)
|
||||
|
||||
collides_with = self.check_collides(sprite, colliders)
|
||||
collides_with = self.check_collides(sprite, colliders, tick_data.screen_transform)
|
||||
for collider in collides_with:
|
||||
if collider is not None:
|
||||
if sprite.is_collider and collider.is_collider:
|
||||
|
@ -157,13 +160,14 @@ class PhysicsElementsHandler:
|
|||
|
||||
return collides_with_last
|
||||
|
||||
def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite]) -> list[StaticSprite]:
|
||||
def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite], screen_transform: PositionScale) -> list[StaticSprite]:
|
||||
collides_with = []
|
||||
|
||||
for collider in colliders:
|
||||
if sprite is not collider:
|
||||
distance = self.calculate_basic_distance(sprite, collider)
|
||||
if distance > 50:
|
||||
if distance > max(self.get_sprite_size_for_distance(sprite, screen_transform),
|
||||
self.get_sprite_size_for_distance(collider, screen_transform)):
|
||||
continue
|
||||
if sprite.collides_with(collider, TOLERANCE):
|
||||
collides_with.append(collider)
|
||||
|
@ -175,3 +179,10 @@ class PhysicsElementsHandler:
|
|||
def calculate_basic_distance(self, sprite1: StaticSprite, sprite2: StaticSprite) -> float:
|
||||
return math.sqrt((sprite1.position_scale.position[0] - sprite2.position_scale.position[0]) ** 2 +
|
||||
(sprite1.position_scale.position[1] - sprite2.position_scale.position[1]) ** 2)
|
||||
|
||||
def get_sprite_size_for_distance(self, ui_element: UiElement, screen_transform: PositionScale) -> int:
|
||||
image = ui_element.render_sprite_image()
|
||||
if image is None:
|
||||
return 0
|
||||
return max(image.get_width() * ui_element.position_scale.scale[0] * screen_transform.scale[0],
|
||||
image.get_height() * ui_element.position_scale.scale[1] * screen_transform.scale[1])
|
||||
|
|
Loading…
Reference in New Issue