Coyote time and jump buffer, walljump fix
This commit is contained in:
parent
36595e81ec
commit
7fd2c58218
@ -1,9 +1,11 @@
|
|||||||
extends Player
|
extends Player
|
||||||
|
|
||||||
export var init_boost := false
|
export var init_boost := false
|
||||||
|
export var jump_buffer_filled := false
|
||||||
onready var wall_touch_direction = 0
|
onready var wall_touch_direction = 0
|
||||||
onready var left_wall_raycasts = $WallRaycasts/LeftWallRaycast
|
onready var left_wall_raycasts = $WallRaycasts/LeftWallRaycast
|
||||||
onready var right_wall_raycasts = $WallRaycasts/RightWallRaycast
|
onready var right_wall_raycasts = $WallRaycasts/RightWallRaycast
|
||||||
|
onready var player_state_machine = $PlayerStateMachine
|
||||||
|
|
||||||
|
|
||||||
func _on_EnemyDetector_area_entered(area: Area2D) -> void:
|
func _on_EnemyDetector_area_entered(area: Area2D) -> void:
|
||||||
@ -14,6 +16,10 @@ func _on_EnemyDetector_body_entered(body: Node) -> void:
|
|||||||
die()
|
die()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_JumpBufferTimer_timeout() -> void:
|
||||||
|
jump_buffer_filled = false
|
||||||
|
|
||||||
|
|
||||||
func handle_grounded_movement(delta: float, direction: Vector2) -> Vector2:
|
func handle_grounded_movement(delta: float, direction: Vector2) -> Vector2:
|
||||||
return calculate_grounded_velocity(_velocity, delta, direction)
|
return calculate_grounded_velocity(_velocity, delta, direction)
|
||||||
|
|
||||||
@ -33,7 +39,7 @@ func handle_wallslide_movement(delta: float, direction: Vector2) -> Vector2:
|
|||||||
func calculate_grounded_velocity(
|
func calculate_grounded_velocity(
|
||||||
linear_velocity: Vector2, delta: float, direction: Vector2
|
linear_velocity: Vector2, delta: float, direction: Vector2
|
||||||
) -> Vector2:
|
) -> Vector2:
|
||||||
var state = self.get_node("PlayerStateMachine").state
|
var state = player_state_machine.state
|
||||||
var out_vel := linear_velocity
|
var out_vel := linear_velocity
|
||||||
var velocity_direction = 1.0
|
var velocity_direction = 1.0
|
||||||
if _velocity.x < 0:
|
if _velocity.x < 0:
|
||||||
@ -86,12 +92,16 @@ func calculate_grounded_velocity(
|
|||||||
)
|
)
|
||||||
elif ! reverse_move:
|
elif ! reverse_move:
|
||||||
out_vel.x = max_velocity[state] * direction.x
|
out_vel.x = max_velocity[state] * direction.x
|
||||||
# Jumping when grounded
|
# Jumping when grounded or jump is buffered
|
||||||
if Input.is_action_just_pressed("jump"):
|
if Input.is_action_just_pressed("jump") || jump_buffer_filled:
|
||||||
return calculate_jump_velocity(_velocity, delta, direction)
|
return calculate_jump_velocity(_velocity, delta, direction)
|
||||||
|
|
||||||
|
elif player_state_machine.coyote_hanging:
|
||||||
|
out_vel.y = 0
|
||||||
|
|
||||||
else:
|
else:
|
||||||
out_vel.y = _gravity * delta
|
out_vel.y = _gravity * delta
|
||||||
|
|
||||||
return out_vel
|
return out_vel
|
||||||
|
|
||||||
|
|
||||||
@ -105,7 +115,6 @@ func is_reversing_horizontal_movement(direction: Vector2) -> bool:
|
|||||||
# Returns if the character is touching a wall with its whole body
|
# Returns if the character is touching a wall with its whole body
|
||||||
# Being able to touch a vertical surface over this length also makes it a qualified "wall"
|
# Being able to touch a vertical surface over this length also makes it a qualified "wall"
|
||||||
# Also sets wall_touch_direction
|
# Also sets wall_touch_direction
|
||||||
# TODO Ugly side effect
|
|
||||||
# TODO Walljumping is a bit to radical behaving
|
# TODO Walljumping is a bit to radical behaving
|
||||||
func is_touching_wall_completely() -> bool:
|
func is_touching_wall_completely() -> bool:
|
||||||
for left_raycast in left_wall_raycasts.get_children():
|
for left_raycast in left_wall_raycasts.get_children():
|
||||||
@ -150,7 +159,10 @@ func calculate_jump_velocity(
|
|||||||
) -> Vector2:
|
) -> Vector2:
|
||||||
var state = self.get_node("PlayerStateMachine").state
|
var state = self.get_node("PlayerStateMachine").state
|
||||||
|
|
||||||
if Input.is_action_just_pressed("jump") && state != "jump":
|
if (
|
||||||
|
Input.is_action_just_pressed("jump") && state != "jump"
|
||||||
|
|| jump_buffer_filled && state != "jump"
|
||||||
|
):
|
||||||
var additive_jump_force = (
|
var additive_jump_force = (
|
||||||
velocity_jump_boost_ratio
|
velocity_jump_boost_ratio
|
||||||
* abs(_velocity.x)
|
* abs(_velocity.x)
|
||||||
@ -163,10 +175,12 @@ func calculate_jump_velocity(
|
|||||||
if (
|
if (
|
||||||
is_touching_wall_completely()
|
is_touching_wall_completely()
|
||||||
&& is_correct_walljump_input(direction)
|
&& is_correct_walljump_input(direction)
|
||||||
|
&& ! is_on_floor()
|
||||||
):
|
):
|
||||||
# The faster you are moving up the farther the walljump goes
|
# The faster you are moving up the farther the walljump goes
|
||||||
linear_velocity.y = (acceleration_force["walljump"].y / mass) * -1
|
linear_velocity.y = (acceleration_force["walljump"].y / mass) * -1
|
||||||
linear_velocity.x += max_velocity["walljump"] * direction.x
|
linear_velocity.x += max_velocity["walljump"] * direction.x
|
||||||
|
|
||||||
if ! Input.is_action_pressed("jump"):
|
if ! Input.is_action_pressed("jump"):
|
||||||
# TODO This is so good not gonna lie
|
# TODO This is so good not gonna lie
|
||||||
if _velocity.y > _gravity * delta * 10:
|
if _velocity.y > _gravity * delta * 10:
|
||||||
@ -176,14 +190,18 @@ func calculate_jump_velocity(
|
|||||||
max(abs(linear_velocity.y), _gravity * delta)
|
max(abs(linear_velocity.y), _gravity * delta)
|
||||||
/ 2
|
/ 2
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
linear_velocity.y += _gravity * delta * 0.88
|
linear_velocity.y += _gravity * delta
|
||||||
|
|
||||||
if _velocity.x == 0:
|
if _velocity.x == 0:
|
||||||
linear_velocity.x += inair_velocity * direction.x
|
linear_velocity.x += inair_velocity * direction.x
|
||||||
|
|
||||||
return linear_velocity
|
return linear_velocity
|
||||||
|
|
||||||
|
|
||||||
# Only applicable to downwards gravity
|
# Only applicable to downwards gravity
|
||||||
|
# Can set the jump buffer
|
||||||
func calculate_fall_velocity(
|
func calculate_fall_velocity(
|
||||||
linear_velocity: Vector2, delta: float, direction: Vector2
|
linear_velocity: Vector2, delta: float, direction: Vector2
|
||||||
) -> Vector2:
|
) -> Vector2:
|
||||||
@ -193,6 +211,8 @@ func calculate_fall_velocity(
|
|||||||
linear_velocity.y = max_velocity["fall"]
|
linear_velocity.y = max_velocity["fall"]
|
||||||
if _velocity.x == 0:
|
if _velocity.x == 0:
|
||||||
linear_velocity.x += inair_velocity * direction.x
|
linear_velocity.x += inair_velocity * direction.x
|
||||||
|
if Input.is_action_just_pressed("jump"):
|
||||||
|
jump_buffer_filled = true
|
||||||
return linear_velocity
|
return linear_velocity
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,14 @@ shape = SubResource( 2 )
|
|||||||
[node name="PlayerStateMachine" type="Node" parent="."]
|
[node name="PlayerStateMachine" type="Node" parent="."]
|
||||||
script = ExtResource( 2 )
|
script = ExtResource( 2 )
|
||||||
|
|
||||||
|
[node name="JumpBufferTimer" type="Timer" parent="PlayerStateMachine"]
|
||||||
|
wait_time = 0.034
|
||||||
|
one_shot = true
|
||||||
|
|
||||||
|
[node name="CoyoteTimer" type="Timer" parent="PlayerStateMachine"]
|
||||||
|
wait_time = 0.034
|
||||||
|
one_shot = true
|
||||||
|
|
||||||
[node name="StateLabel" type="Label" parent="."]
|
[node name="StateLabel" type="Label" parent="."]
|
||||||
margin_left = -25.3386
|
margin_left = -25.3386
|
||||||
margin_top = -34.2836
|
margin_top = -34.2836
|
||||||
@ -93,3 +101,4 @@ collision_mask = 9
|
|||||||
|
|
||||||
[connection signal="area_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_area_entered"]
|
[connection signal="area_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_area_entered"]
|
||||||
[connection signal="body_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_body_entered"]
|
[connection signal="body_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_body_entered"]
|
||||||
|
[connection signal="timeout" from="PlayerStateMachine/JumpBufferTimer" to="." method="_on_JumpBufferTimer_timeout"]
|
||||||
|
|||||||
@ -14,10 +14,10 @@ var velocity_jump_boost_ratio := 0.1967
|
|||||||
var init_acceleration_force := {"walk": 4181, "run": 6765, "idle": 4181}
|
var init_acceleration_force := {"walk": 4181, "run": 6765, "idle": 4181}
|
||||||
# newtonmeters is the unit
|
# newtonmeters is the unit
|
||||||
var acceleration_force := {
|
var acceleration_force := {
|
||||||
"walk": Vector2(2584, 2000),
|
"walk": Vector2(2584, 2200),
|
||||||
"idle": Vector2(2584, 2000),
|
"idle": Vector2(2584, 2200),
|
||||||
"run": Vector2(2584, 2000),
|
"run": Vector2(2584, 2200),
|
||||||
"walljump": Vector2(2548, 2000)
|
"walljump": Vector2(2548, 2200)
|
||||||
}
|
}
|
||||||
var _gravity := 1667.0
|
var _gravity := 1667.0
|
||||||
# Kilograms
|
# Kilograms
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
extends StateMachine
|
extends StateMachine
|
||||||
|
|
||||||
|
onready var coyoteTimer = $CoyoteTimer
|
||||||
|
export var coyote_hanging = false
|
||||||
|
onready var jumpBufferTimer = $JumpBufferTimer
|
||||||
|
|
||||||
|
|
||||||
# Adds the intial states
|
# Adds the intial states
|
||||||
func _ready():
|
func _ready():
|
||||||
@ -18,11 +22,11 @@ func _state_logic(delta):
|
|||||||
# RayCasts for visual debugging
|
# RayCasts for visual debugging
|
||||||
# TODO Global context switch for debug/build mode
|
# TODO Global context switch for debug/build mode
|
||||||
# \ is for new line in multiline statements
|
# \ is for new line in multiline statements
|
||||||
parent.get_node("CollisionShape2D/RayCaster")._raycast(
|
# parent.get_node("CollisionShape2D/RayCaster")._raycast(
|
||||||
Vector2.DOWN,
|
# Vector2.DOWN,
|
||||||
parent.get_node("CollisionShape2D").get_shape(),
|
# parent.get_node("CollisionShape2D").get_shape(),
|
||||||
parent.collision_mask
|
# parent.collision_mask
|
||||||
)
|
# )
|
||||||
|
|
||||||
var handle_input_ref
|
var handle_input_ref
|
||||||
|
|
||||||
@ -94,25 +98,42 @@ func _get_transition(delta):
|
|||||||
if ! parent.is_on_floor():
|
if ! parent.is_on_floor():
|
||||||
if parent._velocity.y < 0:
|
if parent._velocity.y < 0:
|
||||||
new_state = states.jump
|
new_state = states.jump
|
||||||
|
|
||||||
if parent._velocity.y >= 0:
|
if parent._velocity.y >= 0:
|
||||||
# if self.state == states.run:
|
|
||||||
# parent._velocity.y = 0
|
|
||||||
new_state = states.fall
|
new_state = states.fall
|
||||||
if (
|
if (
|
||||||
parent.is_touching_wall_completely()
|
parent.is_touching_wall_completely()
|
||||||
&& parent._velocity.y <= parent.wallslide_threshold
|
&& parent._velocity.y <= parent.wallslide_threshold
|
||||||
):
|
):
|
||||||
|
# TODO Wallslide might be too long
|
||||||
new_state = states.wallslide
|
new_state = states.wallslide
|
||||||
|
# Begins coyote time only if walking from ledge
|
||||||
|
elif [states.walk, states.run].has(self.state) && ! coyote_hanging:
|
||||||
|
coyoteTimer.start()
|
||||||
|
coyote_hanging = true
|
||||||
|
|
||||||
|
if new_state == states.fall && jumpBufferTimer.is_stopped():
|
||||||
|
jumpBufferTimer.start()
|
||||||
|
|
||||||
|
if (
|
||||||
|
coyoteTimer.is_stopped()
|
||||||
|
|| [states.idle, states.jump].has(self.state)
|
||||||
|
):
|
||||||
|
coyote_hanging = false
|
||||||
|
if coyote_hanging:
|
||||||
|
new_state = self.state
|
||||||
|
|
||||||
elif parent._velocity.x != 0:
|
elif parent._velocity.x != 0:
|
||||||
if Input.is_action_pressed("boost_move"):
|
if Input.is_action_pressed("boost_move"):
|
||||||
new_state = states.run
|
new_state = states.run
|
||||||
else:
|
else:
|
||||||
new_state = states.walk
|
new_state = states.walk
|
||||||
|
coyote_hanging = false
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# TODO How does this apply to enviornment induced movement?
|
# TODO How does this apply to enviornment induced movement?
|
||||||
new_state = states.idle
|
new_state = states.idle
|
||||||
|
coyote_hanging = false
|
||||||
if new_state != self.state:
|
if new_state != self.state:
|
||||||
return new_state
|
return new_state
|
||||||
parent.init_boost = false
|
parent.init_boost = false
|
||||||
|
|||||||
@ -58,7 +58,6 @@ tile_data = PoolIntArray( 0, 0, 0, 65536, 0, 0, 131072, 0, 0, 196608, 0, 0, 2621
|
|||||||
|
|
||||||
[node name="Blobby" parent="." instance=ExtResource( 1 )]
|
[node name="Blobby" parent="." instance=ExtResource( 1 )]
|
||||||
position = Vector2( 131, 560 )
|
position = Vector2( 131, 560 )
|
||||||
gravity = 4000.0
|
|
||||||
|
|
||||||
[node name="Camera2D" parent="Blobby" index="2"]
|
[node name="Camera2D" parent="Blobby" index="2"]
|
||||||
limit_right = 85000
|
limit_right = 85000
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user