from level.elements.dynamic.PushableBoxLevelElement import PushableBoxLevelElement 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 class PlayerSprite(DynamicSprite): def __init__(self, spritesheet: Spritesheet): super().__init__(spritesheet) self.jump_time = -1 self.allowed_jump_time = 12 self.acceleration_horizontal = 2 self.deceleration_horizontal_air = 0.2 self.deceleration_horizontal_ground = 0.4 self.gravity = 9.81 / 11 self.max_motion_horizontal_via_input = 5 self.id = 'player' # animation properties self.no_motion_since = 100 self.last_directional_input = KeyManager.KEY_RIGHT self.is_potentially_stuck = 0 def tick(self, tick_data: TickData): super().tick(tick_data) left = self.get_collides_with_direction(CollisionDirection.LEFT) right = self.get_collides_with_direction(CollisionDirection.RIGHT) bottom = self.get_collides_with_direction(CollisionDirection.BOTTOM) if self.is_potentially_stuck == 0 and left and bottom: if left.secondary_sprite == bottom.secondary_sprite: if isinstance(left.secondary_sprite, PushableBoxLevelElement): self.is_potentially_stuck = 1 else: self.is_potentially_stuck = 0 else: self.is_potentially_stuck = 0 elif self.is_potentially_stuck == 1 and right and bottom: if right.secondary_sprite == bottom.secondary_sprite: if isinstance(right.secondary_sprite, PushableBoxLevelElement): self.is_potentially_stuck = 2 else: self.is_potentially_stuck = 0 else: self.is_potentially_stuck = 0 if self.is_potentially_stuck == 2: self.position_scale.position = (self.position_scale.position[0] - 2, self.position_scale.position[1] - 5) self.is_potentially_stuck = 0 if tick_data.key_manager.is_keymap_down(KeyManager.KEY_RIGHT): self.last_directional_input = 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): self.last_directional_input = 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.65) if self.jump_time >= 0: self.jump_time -= 1 # update animation state if self.last_directional_input == KeyManager.KEY_RIGHT: animation_dir = 'r' else: animation_dir = 'l' if abs(self.motion[0]) < 0.1: self.no_motion_since += tick_data.dt else: self.no_motion_since = 0 if self.no_motion_since > 20: self.set_animation_state('idle_' + animation_dir) else: self.set_animation_state('walk_' + animation_dir)