class_name PlatformerPlayerAirMove extends PlatformerPlayerMove ## Move that controls a player actor while jumping or falling # ----------------------------------------------------------------------------------------------- # ## Whether the air move was acrivated because the player jumped var jumped : bool = false #var _was_activated_by_jumping : bool = false var _most_recent_vertical_velocity : float = 0.0 # ----------------------------------------------------------------------------------------------- # ## Called when the actor controller has started performing the move ## @param delta_seconds Elapsed time since the previous frame func _move_started() -> void: enable_gravity(true) actor_controller.consecutive_jump_count += 1 _most_recent_vertical_velocity = 0.0 # ----------------------------------------------------------------------------------------------- # ## Called once per physics frame to update the state of the simulation ## @param delta_seconds Time that has elapsed since the last physics frame func _physics_process(delta_seconds : float) -> void: # If this is the first jump frame, don't check grounding (the actor is # still grounded and just jumping off) if jumped: give_vertical_jump_impulse(actor_abilities.jump_height, delta_seconds) jumped = false else: # Update the grounded state (the actor's physics component will have # moved it before or after this code ran, so the isGrounded state is now stale) var is_grounded : bool = self.is_grounded if is_grounded: var vertical_velocity : float = get_vertical_velocity() var ground_velocity : Vector3 = Vector3(0.0, 0.0, 0.0) # TODO is_grounded = is_grounded and (vertical_velocity <= ground_velocity.y) # If the actor has impacted the ground, return to the ground move if is_grounded: switch_to_ground_move(_most_recent_vertical_velocity) # We have not done anything yet, so continue update in ground move actor_controller.move._physics_process(delta_seconds) return else: _most_recent_vertical_velocity = get_vertical_velocity() # Player is still in the air, so do air-based movement _handle_horizontal_movement(delta_seconds) if Input.is_action_just_pressed("dash"): if actor_abilities.can_air_dash: switch_to_dash_move() return if Input.is_action_just_pressed("jump"): if actor_controller.consecutive_jump_count < actor_abilities.jump_count: switch_to_air_move(true) return # ----------------------------------------------------------------------------------------------- # ## Movement logic to move the actor to the left and right ## @param delta_seconds Amount of time that has passed since the last physics frame func _handle_horizontal_movement(delta_seconds : float): var horizontal_input = ( Input.get_action_strength("move_right") - Input.get_action_strength("move_left") ) # Determine the speed at which the player wants to move and the highest # possible speed the actor could achieve (used to calculate acceleration) var fastest_speed = _get_movement_speed() var target_speed = fastest_speed * horizontal_input var acceleration = fastest_speed / actor_abilities.seconds_to_full_speed acceleration *= actor_abilities.air_control_factor # Adjust for air control! accelerate_to_velocity(target_speed, acceleration, delta_seconds) # Turn the actor towards the direction the player is directing var horizontal_direction : float = get_horizontal_velocity() if horizontal_direction < actor_abilities.walking_speed * -0.1: actor_controller.facing_direction = -1.0 elif horizontal_direction > actor_abilities.walking_speed * 0.1: actor_controller.facing_direction = +1.0 # ----------------------------------------------------------------------------------------------- # ## Returns the speed at which the actor should move ## @returns The speed at which the actor should move func _get_movement_speed() -> float: if self.actor_abilities.can_sprint and Input.is_action_held("sprint"): return self.actor_abilities.running_speed else: return self.actor_abilities.walking_speed