From 30c153e555b47f3fe4fc21508134b13f806eda4f Mon Sep 17 00:00:00 2001 From: Yan Wittmann Date: Sat, 25 Mar 2023 18:14:47 +0100 Subject: [PATCH] Physics engine improvements --- doc/levels/demo.txt | 48 --------------------- project/main.py | 6 +-- project/physics/PhysicsElementsHandler.py | 51 +++++++++++++++++++---- project/sprite/DynamicSprite.py | 37 +++++++++++++++- project/sprite/Sprite.py | 19 --------- project/sprite/StaticSprite.py | 12 ------ 6 files changed, 82 insertions(+), 91 deletions(-) delete mode 100644 doc/levels/demo.txt diff --git a/doc/levels/demo.txt b/doc/levels/demo.txt deleted file mode 100644 index 6544f65..0000000 --- a/doc/levels/demo.txt +++ /dev/null @@ -1,48 +0,0 @@ -1-1 -ghost-house -dash - - - - - - - - - - - - - - - - - - - - - - - - - - - - -########## -########## -########## -########## -########## -########## -########## -########## -########## -########## -########## -########## -########## - -3, 4, HEBEL-1, 0 -23, 34, HEBEL-2, 0 -10, 10, HEBEL-1; HEBEL-2 diff --git a/project/main.py b/project/main.py index b05acd9..2fa252b 100644 --- a/project/main.py +++ b/project/main.py @@ -38,7 +38,7 @@ elif what_to_run == 'physics': screen = pygame.display.set_mode((600, 500)) pygame.display.set_caption("PE GAME") clock = pygame.time.Clock() - frame_rate = 50 + frame_rate = 80 spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json") @@ -61,11 +61,11 @@ elif what_to_run == 'physics': while True: clock.tick(frame_rate) - skip = False + skip = True for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() - exit(0) + quit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_RIGHT: skip = False diff --git a/project/physics/PhysicsElementsHandler.py b/project/physics/PhysicsElementsHandler.py index 1a63cdb..78b4a70 100644 --- a/project/physics/PhysicsElementsHandler.py +++ b/project/physics/PhysicsElementsHandler.py @@ -45,23 +45,60 @@ class PhysicsElementsHandler: def attempt_move(self, sprite: DynamicSprite, colliders: list[StaticSprite], motion_steps: int) -> bool: total_motion = sprite.motion motion_step = (total_motion[0] / motion_steps, total_motion[1] / motion_steps) + # print(motion_step) for i in range(motion_steps): + sprite.reset_touches() + sprite.position_scale.position = ( sprite.position_scale.position[0] + motion_step[0], + sprite.position_scale.position[1] + ) + + if self.check_collides(sprite, colliders): + sprite.position_scale.position = ( + sprite.position_scale.position[0] - motion_step[0], + sprite.position_scale.position[1] + ) + + if sprite.motion[0] > 0: + sprite.set_touches_right(True) + + if sprite.motion[0] < 0: + sprite.set_touches_left(True) + + sprite.motion = (0, sprite.motion[1]) + return False + + sprite.position_scale.position = ( + sprite.position_scale.position[0], sprite.position_scale.position[1] + motion_step[1] ) - for collider in colliders: - if sprite is not collider and sprite.collides_with(collider, TOLERANCE): - sprite.position_scale.position = ( - sprite.position_scale.position[0] - motion_step[0], - sprite.position_scale.position[1] - motion_step[1] - ) - return False + if self.check_collides(sprite, colliders): + sprite.position_scale.position = ( + sprite.position_scale.position[0], + sprite.position_scale.position[1] - motion_step[1] + ) + + if sprite.motion[1] > 0: + sprite.set_touches_bottom(True) + + if sprite.motion[1] < 0: + sprite.set_touches_top(True) + + sprite.motion = (sprite.motion[0], 0) + return False return True + def check_collides(self, sprite: StaticSprite, colliders: list[StaticSprite]) -> bool: + for collider in colliders: + if sprite is not collider and sprite.collides_with(collider, TOLERANCE): + return True + + return False + def draw(self, screen: Surface, screen_transform: PositionScale): for sprite in self.sprites: sprite.draw(screen, screen_transform) diff --git a/project/sprite/DynamicSprite.py b/project/sprite/DynamicSprite.py index 2f93a11..a3c7651 100644 --- a/project/sprite/DynamicSprite.py +++ b/project/sprite/DynamicSprite.py @@ -13,13 +13,46 @@ class DynamicSprite(StaticSprite): super().__init__(spritesheet) self.motion = (0, 0) - self.deceleration_horizontal = 0 + + self.deceleration_horizontal_air = 0.02 + self.deceleration_horizontal_ground = 0.3 self.gravity = 9.81 / 10 + # up, right, down, left + self.touches_bounding = (False, False, False, False) + + 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) + def tick(self, dt: float): super().tick(dt) + # self.motion = ( + # self.motion[0] - self.deceleration_horizontal * dt, + # self.motion[1] + self.gravity * dt + # ) + # wrong implementation. Make deceleration_horizontal only until 0 is reached. multiply value with motion + + deceleration_horizontal = 0 + if abs(self.motion[0]) > 0: + if self.touches_bounding[2]: + deceleration_horizontal = self.deceleration_horizontal_ground + else: + deceleration_horizontal = self.deceleration_horizontal_air + self.motion = ( - self.motion[0] - self.deceleration_horizontal * dt, + self.motion[0] - deceleration_horizontal * self.motion[0] * dt, self.motion[1] + self.gravity * dt ) diff --git a/project/sprite/Sprite.py b/project/sprite/Sprite.py index 02ad616..39f36a8 100644 --- a/project/sprite/Sprite.py +++ b/project/sprite/Sprite.py @@ -52,25 +52,6 @@ class Sprite: return if self.image is not None: - # target_position = screen_transform.apply_scale_to_position() - # target_position = ( - # target_position[0] + self.position_scale.position[0], - # target_position[1] + self.position_scale.position[1] - # ) - - # target_scale = ( - # screen_transform.scale[0] * self.position_scale.scale[0], - # screen_transform.scale[1] * self.position_scale.scale[1] - # ) - # target_size = ( - # int(target_scale[0] * self.image.get_width()), - # int(target_scale[1] * self.image.get_height()) - # ) - - # target_image = self.get_scaled_image(self.image, target_size) - - # screen.blit(target_image, target_position) - target_scale = (screen_transform.scale[0] * self.position_scale.scale[0], screen_transform.scale[1] * self.position_scale.scale[1]) diff --git a/project/sprite/StaticSprite.py b/project/sprite/StaticSprite.py index 5efa776..d04ed8b 100644 --- a/project/sprite/StaticSprite.py +++ b/project/sprite/StaticSprite.py @@ -24,18 +24,6 @@ class StaticSprite(Sprite): self_position = self_bounds.get_position() other_position = other_bounds.get_position() - # if self_position[0] + self_dimensions[0] < other_position[0]: - # return False - - # if self_position[0] > other_position[0] + other_dimensions[0]: - # return False - - # if self_position[1] + self_dimensions[1] < other_position[1]: - # return False - - # if self_position[1] > other_position[1] + other_dimensions[1]: - # return False - if self_position[0] + self_dimensions[0] < other_position[0] + tolerance: return False