All Questions

Community

N
Kgothatso Ntuli

Character won't double jump if you go from run to idle state.

My character won't double jump is certain things are met, for example if you start the game walk off a ledge and land then you can't ever double jump again. Also sometimes the double jump is too short.

Move.gd

extends State

"""
Parent state that handles and abstracts basic movemnt used by child move state
"""

export var max_speed_default := Vector2(500.0, 900.0)
export var acceleration_default := Vector2(100000, 3000.0)
export var decceleration_default := Vector2(500, 3000.0)
export var max_speed_fall := 1500.0


var max_speed := max_speed_default
var acceleration := acceleration_default
var decceleration := decceleration_default
var vel := Vector2.ZERO


func _unhandled_input(event: InputEvent) -> void:
	if owner.is_on_floor() and event.is_action_pressed("jump"):
		_state_machine.transition_to("Move/Air", {force = true})


func physics_process(delta: float) -> void:
	vel = calculate_vel(vel, max_speed, acceleration, decceleration, delta, get_move_dir())
	
	vel = owner.move_and_slide(vel, owner.FLOOR_NORMAL)
	# Camera follows mouse.
	Events.emit_signal("player_moved", owner)
	
static func calculate_vel(old_vel: Vector2,
		max_speed: Vector2,
		acceleration: Vector2,
		decceleration: Vector2,
		delta: float,
		move_dir: Vector2,
		max_speed_fall := 1500.0
	) -> Vector2:
	
	var new_vel := old_vel
	new_vel.y += move_dir.y * acceleration.y * delta	
	
	if move_dir.x:
		new_vel.x += move_dir.x * acceleration.x * delta
	elif abs(new_vel.x) > 0.1:
		new_vel.x -= decceleration.x * delta * sign(new_vel.x)
		new_vel.x = new_vel.x if sign(new_vel.x) == sign(old_vel.x) else 0
		
	new_vel.x = clamp(new_vel.x, -max_speed.x, max_speed.x)
	new_vel.y = clamp(new_vel.y, -max_speed.y, max_speed_fall)
	
		
	return new_vel
	

static func get_move_dir() -> Vector2:
	return Vector2(
		Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
		1.0
	)

Air.gd

extends State

export var acceleration_x := 5000.0
export var jump_force := 900.0
export var max_jump_count := 2

var _jump_count := 0

func unhandled_input(event: InputEvent) -> void:
	var move := get_parent()
	if event.is_action_pressed("jump") and _jump_count < max_jump_count:
		jump()
	
	move.unhandled_input(event)


func physics_process(delta: float) -> void:
	var move := get_parent()
	move.physics_process(delta)
	# Landing
	if owner.is_on_floor():
		var target_state := "Move/Idle" if move.get_move_dir().x == 0 else "Move/Run"
		_state_machine.transition_to(target_state)

func enter(msg: Dictionary = {}) -> void:
	var move := get_parent()
	move.enter(msg)
	
	move.acceleration.x = acceleration_x
	if "vel" in msg:
		move.vel = msg.vel
		move.max_speed.x = max(abs(msg.vel.x), move.max_speed.x)
	
	if "force" in msg:
		jump()
	else:
		_jump_count += 1

func exit() -> void:
	var move := get_parent()
	move.acceleration = move.acceleration_default
	move.exit()


func jump() -> void:
	var move := get_parent()
	move.vel += calc_jump_vel(jump_force)
	_jump_count += 0
	move.exit()
"""
Returns new velocity with jump force applied
"""

func calc_jump_vel(force : float = 0.0) -> Vector2:
	var move : State = get_parent()
	return move.calculate_vel(
		move.vel,
		move.max_speed,
		Vector2(0.0, force),
		Vector2.ZERO,
		1.0,
		Vector2.UP
	)


  • Nathan Lovato replied
    Solution

    You need to reset the jump count when you exit the Air state.

    func exit() -> void:
        _jump_count = 0