Merge remote-tracking branch 'origin/main'

main
Jonas Wächter 2023-03-26 17:01:43 +02:00
commit 8b6267e9cb
12 changed files with 185 additions and 108 deletions

View File

@ -12,21 +12,21 @@
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,x,x,x,x,x,x,x,x,x,,,,,,,,,,,,,,,,,D,,, #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,x,x,x,x,x,x,x,x,x,,,,,,,,,,,,,,,,,D,,,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
@ -38,6 +38,4 @@
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
3,3,id=HEBEL,requires=HEBEL;HEBEL-2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1
12
13
14
15 #
16 #
17 #
18 #
19 #
20 #
21 # #
22 # #
23 # #
24 # #
25 # #
26 # #
27 # #
28 # #
29 # x x x x x x x x x D #
30 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
31 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
32 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
38 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
39 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
40 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
41 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
3 3 id=HEBEL requires=HEBEL;HEBEL-2

View File

@ -6,7 +6,7 @@ from level.LevelManager import LevelManager
from level.elements.LoadedLevel import LoadedLevel from level.elements.LoadedLevel import LoadedLevel
from physics.SpriteManager import SpriteManager, DrawLayers from physics.SpriteManager import SpriteManager, DrawLayers
from physics.TickData import TickData from physics.TickData import TickData
from physics.controllers.PlayerSprite import PlayerSprite from physics.sprites.PlayerSprite import PlayerSprite
from sprite.PositionScale import PositionScale 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
@ -47,6 +47,16 @@ if what_to_run == 'level':
generated_level = LoadedLevel(sprite_manager, spritesheet_manager) generated_level = LoadedLevel(sprite_manager, spritesheet_manager)
generated_level.load_level(parsed_levels_manager.levels[0]) 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)
text_1 = TextLabel("Frame: 0", 2, 110, 50, alignment="left")
text_1.position_scale.scale = (0.3, 0.3)
sprite_manager.add_ui_element(DrawLayers.UI, text_1)
ghost_character.debug_label = text_1
while True: while True:
clock.tick(frame_rate) clock.tick(frame_rate)

View File

@ -0,0 +1,14 @@
class CollisionDirection:
LEFT = 0
RIGHT = 1
TOP = 2
BOTTOM = 3
DIRECTION_NAMES = ['LEFT', 'RIGHT', 'TOP', 'BOTTOM']
def __init__(self, direction: int, primary_sprite, secondary_sprite):
self.direction = direction
self.primary_sprite = primary_sprite
self.secondary_sprite = secondary_sprite
def to_string(self):
return 'CollisionDirection.' + CollisionDirection.DIRECTION_NAMES[self.direction]

View File

@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
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.Sprite import Sprite from sprite.Sprite import Sprite
@ -40,6 +41,8 @@ class PhysicsElementsHandler:
# 4.2.3. If it doesn't, move the sprite to the new position # 4.2.3. If it doesn't, move the sprite to the new position
colliders = [sprite for sprite in sprites if isinstance(sprite, StaticSprite) and sprite.is_collider] colliders = [sprite for sprite in sprites if isinstance(sprite, StaticSprite) and sprite.is_collider]
for collider in colliders:
collider.reset_collides_with()
dynamic_sprites = [sprite for sprite in sprites if isinstance(sprite, DynamicSprite)] dynamic_sprites = [sprite for sprite in sprites if isinstance(sprite, DynamicSprite)]
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])
@ -55,56 +58,65 @@ class PhysicsElementsHandler:
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] * dt) / motion_steps, (total_motion[1] * dt) / motion_steps)
collides_with_last = None
collided = [False, False]
sprite.reset_collides_with()
for i in range(motion_steps): for i in range(motion_steps):
sprite.reset_touches() if not collided[0]:
sprite.position_scale.position = (
sprite.position_scale.position[0] + motion_step[0],
sprite.position_scale.position[1]
)
collides_with = self.check_collides(sprite, colliders)
if collides_with is not None:
sprite.position_scale.position = ( sprite.position_scale.position = (
sprite.position_scale.position[0] - motion_step[0], sprite.position_scale.position[0] + motion_step[0],
sprite.position_scale.position[1] sprite.position_scale.position[1]
) )
if sprite.motion[0] > 0: collides_with = self.check_collides(sprite, colliders)
sprite.set_touches_right(True) if collides_with is not None:
sprite.position_scale.position = (
sprite.position_scale.position[0] - motion_step[0],
sprite.position_scale.position[1]
)
if sprite.motion[0] < 0: if sprite.motion[0] > 0:
sprite.set_touches_left(True) sprite.add_collides_with(CollisionDirection(CollisionDirection.RIGHT, sprite, collides_with))
sprite.motion = (0, sprite.motion[1]) if sprite.motion[0] < 0:
return collides_with sprite.add_collides_with(CollisionDirection(CollisionDirection.LEFT, sprite, collides_with))
sprite.position_scale.position = ( sprite.motion = (0, sprite.motion[1])
sprite.position_scale.position[0],
sprite.position_scale.position[1] + motion_step[1]
)
collides_with = self.check_collides(sprite, colliders) collides_with_last = collides_with
if collides_with is not None: collided[0] = True
if not collided[1]:
sprite.position_scale.position = ( sprite.position_scale.position = (
sprite.position_scale.position[0], sprite.position_scale.position[0],
sprite.position_scale.position[1] - motion_step[1] sprite.position_scale.position[1] + motion_step[1]
) )
if sprite.motion[1] > 0: collides_with = self.check_collides(sprite, colliders)
sprite.set_touches_bottom(True) if collides_with is not None:
sprite.position_scale.position = (
sprite.position_scale.position[0],
sprite.position_scale.position[1] - motion_step[1]
)
if sprite.motion[1] < 0: if sprite.motion[1] > 0:
sprite.set_touches_top(True) sprite.add_collides_with(CollisionDirection(CollisionDirection.BOTTOM, sprite, collides_with))
sprite.motion = (sprite.motion[0], 0) if sprite.motion[1] < 0:
return collides_with sprite.add_collides_with(CollisionDirection(CollisionDirection.TOP, sprite, collides_with))
return None sprite.motion = (sprite.motion[0], 0)
collides_with_last = collides_with
collided[1] = True
return collides_with_last
def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite]) -> Optional[StaticSprite]: def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite]) -> Optional[StaticSprite]:
for collider in colliders: for collider in colliders:
if sprite is not collider and sprite.collides_with(collider, TOLERANCE): if sprite is not collider:
return collider if sprite.collides_with(collider, TOLERANCE):
return collider
return None return None

View File

@ -1,6 +1,5 @@
from typing import Optional from typing import Optional
import pygame
from pygame import Surface from pygame import Surface
from physics.PhysicsElementsHandler import PhysicsElementsHandler from physics.PhysicsElementsHandler import PhysicsElementsHandler
@ -57,5 +56,11 @@ class SpriteManager:
return elements return elements
def collision_detected(self, sprite_a: Sprite, sprite_b: Sprite): def collision_detected(self, sprite_a: Sprite, sprite_b: Sprite):
# print(f"Collision detected between {sprite_a} and {sprite_b}")
pass pass
def find_sprite_by_uuid(self, uuid: str) -> Optional[UiElement]:
for layer in DrawLayers.DRAW_ORDER:
for sprite in self.layers[layer]:
if sprite.uuid == uuid:
return sprite
return None

View File

@ -1,24 +0,0 @@
from physics.TickData import TickData
from sprite.DynamicSprite import DynamicSprite
from sprite.Spritesheet import Spritesheet
from ui_elements.KeyManager import KeyManager
from ui_elements.TextLabel import TextLabel
class PlayerSprite(DynamicSprite):
def __init__(self, spritesheet: Spritesheet):
super().__init__(spritesheet)
self.jump_time = -1
self.allowed_jump_time = 20
self.debug_label = TextLabel('', -1, -1)
def tick(self, tick_data: TickData):
super().tick(tick_data)
if tick_data.key_manager.is_keymap_down(KeyManager.KEY_RIGHT):
self.motion = (self.motion[0] + 2, self.motion[1])
if tick_data.key_manager.is_keymap_down(KeyManager.KEY_LEFT):
self.motion = (self.motion[0] - 2, self.motion[1])
self.debug_label.set_text(f'jump: {self.jump_time}, x: {round(self.motion[0], 2)}, y: {round(self.motion[1], 2)}, touches: {self.touches_bounding}')

View File

@ -0,0 +1,11 @@
from physics.TickData import TickData
from sprite.Spritesheet import Spritesheet
from sprite.StaticSprite import StaticSprite
class DeathBox(StaticSprite):
def __init__(self, spritesheet: Spritesheet):
super().__init__(spritesheet)
def tick(self, tick_data: TickData):
super().tick(tick_data)

View File

@ -0,0 +1,45 @@
from physics.CollisionDirection import CollisionDirection
from physics.TickData import TickData
from sprite.DynamicSprite import DynamicSprite
from sprite.Spritesheet import Spritesheet
from ui_elements.KeyManager import KeyManager
from ui_elements.TextLabel import TextLabel
class PlayerSprite(DynamicSprite):
def __init__(self, spritesheet: Spritesheet):
super().__init__(spritesheet)
self.debug_label = TextLabel('', -1, -1)
self.jump_time = -1
self.allowed_jump_time = 12
self.acceleration_horizontal = 2
self.deceleration_horizontal_air = 0.02
self.deceleration_horizontal_ground = 0.3
self.gravity = 9.81 / 10
self.max_motion_horizontal_via_input = 5
def tick(self, tick_data: TickData):
super().tick(tick_data)
if tick_data.key_manager.is_keymap_down(KeyManager.KEY_RIGHT):
if self.motion[0] < self.max_motion_horizontal_via_input:
self.motion = (self.motion[0] + self.acceleration_horizontal, self.motion[1])
if tick_data.key_manager.is_keymap_down(KeyManager.KEY_LEFT):
if self.motion[0] > -self.max_motion_horizontal_via_input:
self.motion = (self.motion[0] - self.acceleration_horizontal, self.motion[1])
if tick_data.key_manager.is_keymap_down(KeyManager.KEY_UP):
if self.jump_time < 0 and self.get_collides_with_direction(CollisionDirection.BOTTOM):
self.jump_time = self.allowed_jump_time
self.motion = (self.motion[0], self.motion[1] - 7)
if self.jump_time >= 0:
self.motion = (self.motion[0], self.motion[1] - 0.5)
if self.jump_time >= 0:
self.jump_time -= 1
self.debug_label.set_text(f'jump: {self.jump_time}, x: {round(self.motion[0], 2)}, y: {round(self.motion[1], 2)}, touches: {list(map(lambda x: x.to_string(), self.get_collides_with()))}')

View File

@ -1,4 +1,4 @@
from sprite.BoundingBox import BoundingBox from physics.CollisionDirection import CollisionDirection
from sprite.Spritesheet import Spritesheet from sprite.Spritesheet import Spritesheet
from sprite.StaticSprite import StaticSprite from sprite.StaticSprite import StaticSprite
from physics.TickData import TickData from physics.TickData import TickData
@ -10,39 +10,23 @@ class DynamicSprite(StaticSprite):
self.motion = (0, 0) self.motion = (0, 0)
self.apply_base_deceleration = True
self.deceleration_horizontal_air = 0.02 self.deceleration_horizontal_air = 0.02
self.deceleration_horizontal_ground = 0.3 self.deceleration_horizontal_ground = 0.3
self.gravity = 9.81 / 10 self.gravity = 9.81 / 10
# up, right, down, left
self.touches_bounding = (False, False, False, False)
def tick(self, tick_data: TickData): def tick(self, tick_data: TickData):
super().tick(tick_data) super().tick(tick_data)
deceleration_horizontal = 0 if self.apply_base_deceleration:
if abs(self.motion[0]) > 0: deceleration_horizontal = 0
if self.touches_bounding[2]: if abs(self.motion[0]) > 0:
deceleration_horizontal = self.deceleration_horizontal_ground if self.get_collides_with_direction(CollisionDirection.BOTTOM):
else: deceleration_horizontal = self.deceleration_horizontal_ground
deceleration_horizontal = self.deceleration_horizontal_air else:
deceleration_horizontal = self.deceleration_horizontal_air
self.motion = ( self.motion = (
self.motion[0] - deceleration_horizontal * self.motion[0] * tick_data.dt, self.motion[0] - deceleration_horizontal * self.motion[0] * tick_data.dt,
self.motion[1] + self.gravity * tick_data.dt self.motion[1] + self.gravity * tick_data.dt
) )
def set_touches_bottom(self, value: bool):
self.touches_bounding = (self.touches_bounding[0], self.touches_bounding[1], value, self.touches_bounding[3])
def set_touches_right(self, value: bool):
self.touches_bounding = (self.touches_bounding[0], value, self.touches_bounding[2], self.touches_bounding[3])
def set_touches_left(self, value: bool):
self.touches_bounding = (self.touches_bounding[0], self.touches_bounding[1], self.touches_bounding[2], value)
def set_touches_top(self, value: bool):
self.touches_bounding = (value, self.touches_bounding[1], self.touches_bounding[2], self.touches_bounding[3])
def reset_touches(self):
self.touches_bounding = (False, False, False, False)

View File

@ -1,7 +1,7 @@
class PositionScale: class PositionScale:
def __init__(self, position: tuple[float, float] = (0, 0), scale: tuple[float, float] = (1, 1)): def __init__(self, position: tuple[float, float] = (0, 0), scale: tuple[float, float] = (1, 1)):
self.position = position self.position: tuple[float, float] = position
self.scale = scale self.scale: tuple[float, float] = scale
def apply_scale_to_position(self): def apply_scale_to_position(self):
return self.position[0] * self.scale[0], self.position[1] * self.scale[1] return self.position[0] * self.scale[0], self.position[1] * self.scale[1]

View File

@ -1,5 +1,8 @@
from typing import Optional
import pygame import pygame
from physics.CollisionDirection import CollisionDirection
from physics.TickData import TickData from physics.TickData import TickData
from sprite.BoundingBox import BoundingBox from sprite.BoundingBox import BoundingBox
from sprite.PositionScale import PositionScale from sprite.PositionScale import PositionScale
@ -22,6 +25,22 @@ class Sprite(UiElement):
self.image = None self.image = None
self.is_collider = True self.is_collider = True
self.collides_with_elements: list[CollisionDirection] = []
def add_collides_with(self, collision_direction: CollisionDirection):
self.collides_with_elements.append(collision_direction)
def reset_collides_with(self):
self.collides_with_elements = []
def get_collides_with(self) -> list[CollisionDirection]:
return self.collides_with_elements
def get_collides_with_direction(self, direction: int) -> Optional[CollisionDirection]:
for collision_direction in self.collides_with_elements:
if collision_direction.direction == direction:
return collision_direction
return None
def tick(self, tick_data: TickData): def tick(self, tick_data: TickData):
animation = self.spritesheet.animations[self.animation_state] animation = self.spritesheet.animations[self.animation_state]

View File

@ -1,4 +1,5 @@
import abc import abc
import uuid
from typing import Optional from typing import Optional
import pygame import pygame
@ -16,6 +17,8 @@ class UiElement:
self.visible = True self.visible = True
self.click_listeners = [] self.click_listeners = []
self.uuid = uuid.uuid4()
def add_click_listener(self, listener): def add_click_listener(self, listener):
self.click_listeners.append(listener) self.click_listeners.append(listener)