From 85a34b01d8cd31f6f39f0341403472ed2ae10d3f Mon Sep 17 00:00:00 2001 From: Yan Wittmann Date: Mon, 27 Mar 2023 18:37:30 +0200 Subject: [PATCH] Added pushable boxes. Added click event handler --- project/data/levels/0-tutorial.csv | 8 +++-- project/data/sprites/movable_box.png | Bin 0 -> 536 bytes project/data/sprites/sprites.json | 13 ++++++++ project/level/Level.py | 2 +- project/level/elements/LevelElement.py | 5 ---- project/level/elements/LoadedLevel.py | 15 +++++----- .../elements/dynamic/DynamicLevelElement.py | 10 +++++++ .../dynamic/PushableBoxLevelElement.py | 18 +++++++++++ .../elements/dynamic/PushableLevelElement.py | 28 ++++++++++++++++++ .../{ => static}/ButtonInputLevelElement.py | 2 +- .../{ => static}/GateReceiverLevelElement.py | 3 +- .../{ => static}/InputLevelElement.py | 2 +- .../{ => static}/LeverInputLevelElement.py | 2 +- .../{ => static}/ReceiverLevelElement.py | 13 ++++---- .../{ => static}/SimpleBlockLevelElement.py | 2 +- .../{ => static}/StaticLevelElement.py | 1 - .../{ => static}/UnknownTileLevelElement.py | 2 +- project/main.py | 9 +++++- project/physics/PhysicsElementsHandler.py | 25 +++++++++++----- 19 files changed, 123 insertions(+), 37 deletions(-) create mode 100644 project/data/sprites/movable_box.png create mode 100644 project/level/elements/dynamic/DynamicLevelElement.py create mode 100644 project/level/elements/dynamic/PushableBoxLevelElement.py create mode 100644 project/level/elements/dynamic/PushableLevelElement.py rename project/level/elements/{ => static}/ButtonInputLevelElement.py (95%) rename project/level/elements/{ => static}/GateReceiverLevelElement.py (91%) rename project/level/elements/{ => static}/InputLevelElement.py (81%) rename project/level/elements/{ => static}/LeverInputLevelElement.py (95%) rename project/level/elements/{ => static}/ReceiverLevelElement.py (84%) rename project/level/elements/{ => static}/SimpleBlockLevelElement.py (93%) rename project/level/elements/{ => static}/StaticLevelElement.py (96%) rename project/level/elements/{ => static}/UnknownTileLevelElement.py (86%) diff --git a/project/data/levels/0-tutorial.csv b/project/data/levels/0-tutorial.csv index 3879df9..2c30b16 100644 --- a/project/data/levels/0-tutorial.csv +++ b/project/data/levels/0-tutorial.csv @@ -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,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +Q,34,id=button-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +F,23,size=7,,weight=0.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/project/data/sprites/movable_box.png b/project/data/sprites/movable_box.png new file mode 100644 index 0000000000000000000000000000000000000000..21731bfac276c19a16e27366928c01d66b7c46a6 GIT binary patch literal 536 zcmV+z0_XjSP)4Tx04UFukvmHRK@^3*7$xEZ3oS$~7JOh4K@>!=kqD-V7D)u7Hp!ZYup5`% z4H9ex8;gL2XydE!A80GsDhPrih}hZtY9y?8j1UnmoMHBUoY`}kIRiBjLpPn;K``^K z9Sw)H*~FX{c*IX90lFDW>W(!Pn~d}4c)P}@>eYbi#s5a*V%pKcS1&xGTed4aE*x2L zEyWwcZF(-bD7+^ewB>-p=Soji_(5^D!Y_*LcyvPUrh01GZ=CwZdd@b5`-OWw%}wP+Hb9-o&1#ivT8CJcshdS1hig4!+a&HuYC@0AigS3bOGBt&?o=5 zEPMb)^=K=VqP@`o000S4OjJexPyqi700000zCKWZ00003bW%=J|Nj8j$_+sP000Sa zNLh0L09-`?09-`@xh-NW0000ZNkl>MT##>zoahQxsaFb6AO aU;qFe+yG%}1A=$}0000": + # 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)) == "", 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])