extends CharacterBody2D ##week2 additions: ## states ## acceleration/deceleration ## hard gravity ## jump buffer ## shove attack @onready var jump_buffer_timer: Timer = $jump_buffer_timer @onready var coyote_timer: Timer = $coyote_timer @onready var right_cast: RayCast2D = $RightCast @onready var left_cast: RayCast2D = $LeftCast @onready var playerGraphic: AnimatedSprite2D = $AnimatedSprite2D const SPEED = 300.0 const JUMP_VELOCITY = -400.0 const PUSH_FORCE:int = 500 @export var bump_power = 50 @export var acceleration:int = 5 @export var hard_gravity:int = 3 enum State{IDLE, RUN, JUMP, FALLING} var current_state: State = State.IDLE enum FaceDirection{LEFT, RIGHT} var facing:FaceDirection = FaceDirection.RIGHT var pushTarget:RigidBody2D var pushEnabled:bool = false func _physics_process(delta: float) -> void: handle_input() update_movement(delta) update_states() update_animation() move_and_slide() handle_collisions() func handle_input() -> void: #Jumping action if Input.is_action_just_pressed("ui_accept"): jump_buffer_timer.start() if is_on_floor() && jump_buffer_timer.time_left > 0: velocity.y = JUMP_VELOCITY current_state = State.JUMP jump_buffer_timer.stop() #Walking action var direction := Input.get_axis("ui_left", "ui_right") #######REFACTOR################ ## Apply acceleration and deceleration to movement if direction == 0: velocity.x = move_toward(velocity.x, 0, acceleration) else: velocity.x = move_toward(velocity.x, SPEED * direction, acceleration) if direction <0: facing=FaceDirection.LEFT playerGraphic.flip_h = true else: facing = FaceDirection.RIGHT playerGraphic.flip_h = false if Input.is_action_just_pressed("shove") && pushEnabled: match facing: FaceDirection.RIGHT: #push right pushTarget.apply_central_impulse(Vector2(1,0) * PUSH_FORCE) pushEnabled = false FaceDirection.LEFT: #push left pushTarget.apply_central_impulse(Vector2(-1,0) * PUSH_FORCE) pushEnabled = false ##Add the hard gravity in here func update_movement(delta:float)-> void: # Add the gravity. if current_state == State.JUMP: #apply normal gravity during up of jump action velocity += get_gravity() * delta else: #Character is falling velocity += get_gravity() * hard_gravity * delta func update_states()->void: match current_state: State.IDLE when velocity.x !=0: current_state = State.RUN ##player stops walking, or starts falling State.RUN: if velocity.x == 0: current_state = State.IDLE ##player walks off of a ledge (no jump) if not is_on_floor() && velocity.y > 0: current_state = State.FALLING ##when jump peaks, we start to fall State.JUMP when velocity.y > 0: current_state = State.FALLING ##player lands, either still or moving State.FALLING when is_on_floor(): if velocity.x == 0: current_state = State.IDLE else: current_state = State.RUN func update_animation()-> void: match current_state: State.IDLE: playerGraphic.play("idle") State.RUN: playerGraphic.play("run") State.JUMP: playerGraphic.play("jump") State.FALLING: playerGraphic.play("fall") func handle_collisions()-> void: #react to objects around for i in get_slide_collision_count(): var c = get_slide_collision(i) if c.get_collider() is RigidBody2D: c.get_collider().apply_central_impulse(-c.get_normal() * bump_power) if right_cast.is_colliding() && facing==FaceDirection.RIGHT: var collider = right_cast.get_collider() if collider is Node && collider is RigidBody2D: pushTarget = collider pushEnabled = true if left_cast.is_colliding() && facing==FaceDirection.LEFT: var collider = left_cast.get_collider() if collider is Node && collider is RigidBody2D: pushTarget = collider pushEnabled = true if not right_cast.is_colliding() and not left_cast.is_colliding(): pushEnabled = false