Added pushable boxes.

Added click event handler
main
Yan Wittmann 2023-03-27 18:37:30 +02:00
parent 6147541a9e
commit 85a34b01d8
19 changed files with 123 additions and 37 deletions

View File

@ -20,7 +20,7 @@
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,, ,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,+,+,+,+,+,+,#,#,#,#,#,#,#,#,#,,,,,,, ,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,+,+,+,+,+,+,#,#,#,#,#,#,#,#,#,,,,,,,
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,, ,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,, ,,,,,M,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,, ,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,+,+,+,+,+,+,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,, ,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,+,+,+,+,+,+,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,, ,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,,,,,,,
@ -31,14 +31,16 @@
,,,,,,,,,,,,,,,,,,,,,,,#,#,,,,,,,,,,,+,+,+,+,+,+,,,,,#,#,#,#,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,#,#,,,,,,,,,,,+,+,+,+,+,+,,,,,#,#,#,#,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,G,,,,,,,,,,,D,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,G,,,,,,,,,,,D,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,L,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,L,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,P,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,P,,,,,,P,,,,,,,,,M,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,#,#,#,#,#,#,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,#,#,#,#,#,+,+,+,+,+,+,+,+,+,+ +,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,#,#,#,#,#,#,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,#,#,#,#,#,+,+,+,+,+,+,+,+,+,+
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
AQ,18,requires_xor=lever-1;button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, AQ,18,requires_xor=lever-1;button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
AU,32,requires_and=lever-1;button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, AU,32,requires_and=lever-1;button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
AJ,33,id=lever-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, AJ,33,id=lever-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Q,34,id=button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, Q,34,id=button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
F,23,size=7,,weight=0.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1
20 # # # # # # # # # # # # # # # # # # # # #
21 # # # # # # # # # + + + + + + # # # # # # # # #
22 # # # # # # # # # # # # # # # # # # # # #
23 M # # # # # # # # # # # # # # # # # #
24 # # # # # # # # # # # # # # # # # #
25 # # # # # # # # # + + + + + + # # # # # # # # #
26 # # # # # # # # # # # # # # # # # #
31 # # + + + + + + # # # #
32 G D
33 L
34 P P M
35 + + + + + + + + + + + + + + + + + + # # # # # # + + + + + + + + + + + + + + + + + + + + + + # # # # # + + + + + + + + + +
36 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
37 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
38 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
39 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
40 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
41
42 AQ 18 requires_xor=lever-1;button-1
43 AU 32 requires_and=lever-1;button-1
44 AJ 33 id=lever-1
45 Q 34 id=button-1
46 F 23 size=7 weight=0.5

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

View File

@ -340,6 +340,19 @@
} }
] ]
}, },
{
"id": "movable_box",
"subsheets": [
{
"id": "1",
"delays": [
1
],
"width": 12,
"height": 12
}
]
},
{ {
"id": "test_1", "id": "test_1",
"subsheets": [ "subsheets": [

View File

@ -34,7 +34,7 @@ class Level:
continue continue
split_item = line[i].split('=') 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] tile[split_item[0]] = split_item[1]
elif split_item[0] in ['requires', 'requires_and', 'requires_or', 'requires_xor']: elif split_item[0] in ['requires', 'requires_and', 'requires_or', 'requires_xor']:
tile[split_item[0]] = split_item[1].split(';') tile[split_item[0]] = split_item[1].split(';')

View File

@ -10,7 +10,6 @@ class LevelElement:
def __init__(self, tile: dict, loaded_level): def __init__(self, tile: dict, loaded_level):
self.tile = tile self.tile = tile
self.loaded_level = loaded_level self.loaded_level = loaded_level
self.sprites = []
if 'id' in tile: if 'id' in tile:
self.id = tile['id'] self.id = tile['id']
@ -20,7 +19,3 @@ class LevelElement:
@abstractmethod @abstractmethod
def load(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, level: Level): def load(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, level: Level):
pass pass
def destroy(self, sprite_manager: SpriteManager):
for sprite in self.sprites:
sprite_manager.remove_ui_element(sprite)

View File

@ -1,12 +1,13 @@
from typing import Optional from typing import Optional
from level.Level import Level from level.Level import Level
from level.elements.ButtonInputLevelElement import ButtonInputLevelElement from level.elements.dynamic.PushableBoxLevelElement import PushableBoxLevelElement
from level.elements.GateReceiverLevelElement import GateReceiverLevelElement from level.elements.static.ButtonInputLevelElement import ButtonInputLevelElement
from level.elements.static.GateReceiverLevelElement import GateReceiverLevelElement
from level.elements.LevelElement import LevelElement from level.elements.LevelElement import LevelElement
from level.elements.LeverInputLevelElement import LeverInputLevelElement from level.elements.static.LeverInputLevelElement import LeverInputLevelElement
from level.elements.SimpleBlockLevelElement import SimpleBlockLevelElement from level.elements.static.SimpleBlockLevelElement import SimpleBlockLevelElement
from level.elements.UnknownTileLevelElement import UnknownTileLevelElement from level.elements.static.UnknownTileLevelElement import UnknownTileLevelElement
from physics import ConstantsParser from physics import ConstantsParser
from physics.SpriteManager import SpriteManager, DrawLayers from physics.SpriteManager import SpriteManager, DrawLayers
from sprite.SpritesheetManager import SpritesheetManager from sprite.SpritesheetManager import SpritesheetManager
@ -24,6 +25,8 @@ TILES = {
'L': LeverInputLevelElement, 'L': LeverInputLevelElement,
'G': GateReceiverLevelElement, 'G': GateReceiverLevelElement,
'M': PushableBoxLevelElement,
} }
@ -48,8 +51,6 @@ class LoadedLevel:
if name in TILES: if name in TILES:
element = TILES[name](tile, self) element = TILES[name](tile, self)
if isinstance(element, LeverInputLevelElement):
print(f"Found lever at {position}")
elif not name == '': elif not name == '':
print(f"Unknown tile at {position}: {name}") print(f"Unknown tile at {position}: {name}")
element = UnknownTileLevelElement(tile, self) element = UnknownTileLevelElement(tile, self)

View File

@ -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)

View File

@ -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']

View File

@ -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])

View File

@ -1,5 +1,5 @@
from level.Level import Level 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.CollisionDirection import CollisionDirection
from physics.SpriteManager import SpriteManager from physics.SpriteManager import SpriteManager
from physics.TickData import TickData from physics.TickData import TickData

View File

@ -1,5 +1,5 @@
from level.Level import Level from level.Level import Level
from level.elements.ReceiverLevelElement import ReceiverLevelElement from level.elements.static.ReceiverLevelElement import ReceiverLevelElement
from physics.SpriteManager import SpriteManager from physics.SpriteManager import SpriteManager
from sprite.SpritesheetManager import SpritesheetManager from sprite.SpritesheetManager import SpritesheetManager
@ -13,7 +13,6 @@ class GateReceiverLevelElement(ReceiverLevelElement):
self.set_animation_state('open' if self.active_state else 'close') self.set_animation_state('open' if self.active_state else 'close')
self.position_scale.position = self.tile['position'] self.position_scale.position = self.tile['position']
def set_active(self, active: bool): def set_active(self, active: bool):
super().set_active(active) super().set_active(active)
self.set_animation_state('open' if self.active_state else 'close') self.set_animation_state('open' if self.active_state else 'close')

View File

@ -1,7 +1,7 @@
from abc import ABC from abc import ABC
from level.elements.StaticLevelElement import StaticLevelElement from level.elements.static.StaticLevelElement import StaticLevelElement
class InputLevelElement(StaticLevelElement, ABC): class InputLevelElement(StaticLevelElement, ABC):

View File

@ -1,5 +1,5 @@
from level.Level import Level 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.CollisionDirection import CollisionDirection
from physics.SpriteManager import SpriteManager from physics.SpriteManager import SpriteManager
from physics.TickData import TickData from physics.TickData import TickData

View File

@ -1,6 +1,6 @@
from abc import ABC from abc import ABC
from level.elements.StaticLevelElement import StaticLevelElement from level.elements.static.StaticLevelElement import StaticLevelElement
from physics.TickData import TickData from physics.TickData import TickData
@ -18,12 +18,16 @@ class ReceiverLevelElement(StaticLevelElement, ABC):
self.requires['xor'] = tile['requires_xor'] self.requires['xor'] = tile['requires_xor']
self.active_state = False self.active_state = False
if 'active_state' in tile: if 'active_state' in tile:
self.set_active(tile['active_state'] == 'True') self.active_state_invert = tile['active_state'] == 'True'
else: else:
self.set_active(False) self.active_state_invert = False
def set_active(self, active: bool): def set_active(self, active: bool):
if self.active_state_invert:
self.active_state = not active
else:
self.active_state = active self.active_state = active
def tick(self, tick_data: TickData): def tick(self, tick_data: TickData):
@ -48,7 +52,6 @@ class ReceiverLevelElement(StaticLevelElement, ABC):
break break
if 'xor' in self.requires: if 'xor' in self.requires:
print(self.requires['xor'])
for requirement in self.requires['xor']: for requirement in self.requires['xor']:
element = self.loaded_level.get_element_by_id(requirement) element = self.loaded_level.get_element_by_id(requirement)
if element and element.emitter_state: if element and element.emitter_state:

View File

@ -1,7 +1,7 @@
import random import random
from level.Level import Level from level.Level import Level
from level.elements.StaticLevelElement import StaticLevelElement from level.elements.static.StaticLevelElement import StaticLevelElement
from physics.SpriteManager import SpriteManager from physics.SpriteManager import SpriteManager
from sprite.SpritesheetManager import SpritesheetManager from sprite.SpritesheetManager import SpritesheetManager

View File

@ -1,4 +1,3 @@
import uuid
from abc import ABC from abc import ABC
from level.elements.LevelElement import LevelElement from level.elements.LevelElement import LevelElement

View File

@ -1,5 +1,5 @@
from level.Level import Level from level.Level import Level
from level.elements.StaticLevelElement import StaticLevelElement from level.elements.static.StaticLevelElement import StaticLevelElement
from physics.SpriteManager import SpriteManager from physics.SpriteManager import SpriteManager
from sprite.SpritesheetManager import SpritesheetManager from sprite.SpritesheetManager import SpritesheetManager

View File

@ -12,6 +12,7 @@ from sprite.PositionScale import PositionScale
from sprite.SpritesheetManager import SpritesheetManager from sprite.SpritesheetManager import SpritesheetManager
from sprite.Sprite import Sprite from sprite.Sprite import Sprite
from sprite.StaticSprite import StaticSprite from sprite.StaticSprite import StaticSprite
from ui_elements import CoordinateTransform
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.LevelMenu import LevelMenu
@ -66,6 +67,12 @@ if what_to_run == 'menu':
key_manager.update_key_events(pygame_events) 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, 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: for event in pygame_events:
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
pygame.quit() pygame.quit()
@ -97,7 +104,7 @@ elif what_to_run == 'level':
parsed_levels_manager.load_from_config('data/levels/levels.json') parsed_levels_manager.load_from_config('data/levels/levels.json')
generated_level = LoadedLevel(sprite_manager, spritesheet_manager) 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 = PlayerSprite(spritesheet_manager.get_sheet("ghost_character"))
ghost_character.position_scale = PositionScale((90, 50), (1, 1)) ghost_character.position_scale = PositionScale((90, 50), (1, 1))
sprite_manager.add_ui_element(DrawLayers.OBJECTS, ghost_character) sprite_manager.add_ui_element(DrawLayers.OBJECTS, ghost_character)

View File

@ -4,6 +4,7 @@ from typing import Optional
from physics.CollisionDirection import CollisionDirection from physics.CollisionDirection import CollisionDirection
from physics.TickData import TickData from physics.TickData import TickData
from sprite.DynamicSprite import DynamicSprite from sprite.DynamicSprite import DynamicSprite
from sprite.PositionScale import PositionScale
from sprite.Sprite import Sprite from sprite.Sprite import Sprite
from sprite.StaticSprite import StaticSprite from sprite.StaticSprite import StaticSprite
from ui_elements.UiElement import UiElement from ui_elements.UiElement import UiElement
@ -26,6 +27,8 @@ class PhysicsElementsHandler:
sprites = [] sprites = []
for layer in layers: for layer in layers:
for sprite in layers[layer]: for sprite in layers[layer]:
# if str(type(sprite)) == "<class 'level.elements.dynamic.PushableBoxLevelElement.PushableBoxLevelElement'>":
# print(f"Found pushable box")
sprite.tick(tick_data) sprite.tick(tick_data)
if isinstance(sprite, Sprite): if isinstance(sprite, Sprite):
sprites.append(sprite) sprites.append(sprite)
@ -51,15 +54,15 @@ class PhysicsElementsHandler:
sorted_dynamic_sprites = sorted(dynamic_sprites, key=lambda spr: spr.position_scale.position[1]) sorted_dynamic_sprites = sorted(dynamic_sprites, key=lambda spr: spr.position_scale.position[1])
for sprite in sorted_dynamic_sprites: 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: if collides_with is not None:
for callback in self.collision_callbacks: for callback in self.collision_callbacks:
callback(sprite, collides_with) 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]: motion_steps: int) -> Optional[StaticSprite]:
total_motion = sprite.motion 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 collides_with_last = None
collided = [False, False] collided = [False, False]
@ -73,7 +76,7 @@ class PhysicsElementsHandler:
# print('Elements: ', list(filter(lambda spr: str(type(spr)) == "<class 'level.elements.LeverInputLevelElement.LeverInputLevelElement'>", colliders))) # 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: for collider in collides_with:
if collider is not None: if collider is not None:
if sprite.is_collider and collider.is_collider: if sprite.is_collider and collider.is_collider:
@ -117,7 +120,7 @@ class PhysicsElementsHandler:
sprite.position_scale.position[1] + motion_step[1] 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: for collider in collides_with:
if collider is not None: if collider is not None:
if sprite.is_collider and collider.is_collider: if sprite.is_collider and collider.is_collider:
@ -157,13 +160,14 @@ class PhysicsElementsHandler:
return collides_with_last 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 = [] collides_with = []
for collider in colliders: for collider in colliders:
if sprite is not collider: if sprite is not collider:
distance = self.calculate_basic_distance(sprite, 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 continue
if sprite.collides_with(collider, TOLERANCE): if sprite.collides_with(collider, TOLERANCE):
collides_with.append(collider) collides_with.append(collider)
@ -175,3 +179,10 @@ class PhysicsElementsHandler:
def calculate_basic_distance(self, sprite1: StaticSprite, sprite2: StaticSprite) -> float: def calculate_basic_distance(self, sprite1: StaticSprite, sprite2: StaticSprite) -> float:
return math.sqrt((sprite1.position_scale.position[0] - sprite2.position_scale.position[0]) ** 2 + 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) (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])