fix: Coyote Time and Jump Buffering

This commit is contained in:
Jakob Feldmann 2023-04-16 17:02:29 +02:00
parent 47775b2b27
commit 650b71e289
7 changed files with 66 additions and 42 deletions

View File

@ -8,7 +8,7 @@ const PhysicsConst = preload("res://src/Utilities/Physic/PhysicsConst.gd")
const FLOOR_NORMAL := Vector2.UP
var stomp_feedback := 1500
var stomp_feedback := 1400
var reset_stomp_time := 0.108
var stomp_time := 0.108
var inair_velocity := 21

View File

@ -257,6 +257,7 @@ func calculate_jump_velocity(
) -> Vector2:
var state = player_state_machine.state
var additive_jump_force = velocity_jump_boost_ratio * abs(velocity.x) * mass
#TODO Single out stomping and make betta
if stomping:
additive_jump_force += stomp_feedback / delta
stomp_time -= delta
@ -446,8 +447,6 @@ func _on_BlobbySkin_body_entered(body: Node) -> void:
if body.is_in_group("harmful") && !levelState.is_dead:
die()
func _on_JumpBufferTimer_timeout() -> void:
jump_buffer_filled = false
# This problem stems from trying to decelerate a walk
# that was caused by the moving environment and not by input

View File

@ -303,7 +303,7 @@ states/wallsliding/node = SubResource( 96 )
states/wallsliding/position = Vector2( 1795.54, 493.009 )
transitions = [ "falling", "wallsliding", SubResource( 138 ), "wallsliding", "idling", SubResource( 139 ), "wallsliding", "wallslideToJump", SubResource( 140 ), "wallslideToJump", "jumping", SubResource( 141 ), "idling", "jumping", SubResource( 147 ), "runToJump", "jumping", SubResource( 148 ), "ducking", "jumping", SubResource( 149 ), "jumping", "jumpToFall", SubResource( 150 ), "jumpToFall", "falling", SubResource( 151 ), "ducking", "duckTurn", SubResource( 152 ), "duckTurn", "ducking", SubResource( 153 ), "falling", "ducking", SubResource( 154 ), "ducking", "falling", SubResource( 155 ), "ducking", "walking", SubResource( 156 ), "walking", "ducking", SubResource( 157 ), "idling", "ducking", SubResource( 158 ), "ducking", "idling", SubResource( 159 ), "ducking", "running", SubResource( 160 ), "running", "ducking", SubResource( 161 ), "running", "falling", SubResource( 162 ), "falling", "running", SubResource( 163 ), "walking", "falling", SubResource( 164 ), "falling", "walking", SubResource( 165 ), "falling", "idling", SubResource( 166 ), "idling", "walking", SubResource( 167 ), "walking", "idling", SubResource( 168 ), "walking", "turnToRun", SubResource( 169 ), "turnToRun", "walking", SubResource( 170 ), "running", "turnToRun", SubResource( 171 ), "turnToRun", "running", SubResource( 172 ), "idling", "idleTurn", SubResource( 173 ), "walking", "idleTurn", SubResource( 174 ), "idleTurn", "walking", SubResource( 175 ), "idling", "turnToRun", SubResource( 176 ), "turnToRun", "idling", SubResource( 177 ), "running", "runToJump", SubResource( 178 ), "wallsliding", "falling", SubResource( 137 ), "jumping", "wallsliding", SubResource( 189 ), "jumping", "idling", SubResource( 193 ), "jumping", "walking", SubResource( 194 ), "runToJump", "wallsliding", SubResource( 195 ), "jumpToFall", "idling", SubResource( 196 ) ]
start_node = "idling"
graph_offset = Vector2( 1078.54, -151.431 )
graph_offset = Vector2( 1027.54, -183.431 )
[sub_resource type="AnimationNodeStateMachinePlayback" id=48]
@ -1243,7 +1243,7 @@ tracks/2/keys = {
}
[sub_resource type="Animation" id=6]
length = 0.13
length = 0.14
loop = true
tracks/0/type = "value"
tracks/0/path = NodePath(".:frame")
@ -1291,7 +1291,7 @@ tracks/3/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 12.5424, 10.5247 ) ]
"values": [ Vector2( 11, 10.525 ) ]
}
tracks/4/type = "value"
tracks/4/path = NodePath("../BlobbyBody:position")
@ -1315,7 +1315,7 @@ tracks/5/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( -12, -12.638 ) ]
"values": [ Vector2( -10.5, -13 ) ]
}
tracks/6/type = "value"
tracks/6/path = NodePath("../WallRaycasts/LeftWallRaycast/Left_Wallcast2:position")
@ -1327,7 +1327,7 @@ tracks/6/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( -12, -4.993 ) ]
"values": [ Vector2( -10.5, -5 ) ]
}
tracks/7/type = "value"
tracks/7/path = NodePath("../WallRaycasts/RightWallRaycast/Right_Wallcast1:position")
@ -1339,7 +1339,7 @@ tracks/7/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 13, -12.638 ) ]
"values": [ Vector2( 11.5, -13 ) ]
}
tracks/8/type = "value"
tracks/8/path = NodePath("../WallRaycasts/RightWallRaycast/Right_Wallcast2:position")
@ -1351,7 +1351,7 @@ tracks/8/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 13, -4.993 ) ]
"values": [ Vector2( 11.5, -5 ) ]
}
tracks/9/type = "value"
tracks/9/path = NodePath(".:offset")
@ -1440,7 +1440,7 @@ tracks/3/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 12.5424, 10.5247 ) ]
"values": [ Vector2( 11, 10.525 ) ]
}
tracks/4/type = "value"
tracks/4/path = NodePath("../BlobbyBody:position")
@ -1464,7 +1464,7 @@ tracks/5/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( -13, -12.638 ) ]
"values": [ Vector2( -11, -13 ) ]
}
tracks/6/type = "value"
tracks/6/path = NodePath("../WallRaycasts/LeftWallRaycast/Left_Wallcast2:position")
@ -1476,7 +1476,7 @@ tracks/6/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( -13, -4.993 ) ]
"values": [ Vector2( -11.5, -5 ) ]
}
tracks/7/type = "value"
tracks/7/path = NodePath("../WallRaycasts/RightWallRaycast/Right_Wallcast1:position")
@ -1488,7 +1488,7 @@ tracks/7/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 12, -12.638 ) ]
"values": [ Vector2( 10.5, -13 ) ]
}
tracks/8/type = "value"
tracks/8/path = NodePath("../WallRaycasts/RightWallRaycast/Right_Wallcast2:position")
@ -1500,7 +1500,7 @@ tracks/8/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 0,
"values": [ Vector2( 12, -4.993 ) ]
"values": [ Vector2( 10.5, -5 ) ]
}
tracks/9/type = "value"
tracks/9/path = NodePath(".:offset")
@ -4623,7 +4623,7 @@ parameters/runToJump/blend_position = 1.0
parameters/running/blend_position = 1.00239
parameters/turnToRun/blend_position = 1.0
parameters/walking/blend_position = 1.0
parameters/wallslideToJump/blend_position = -0.178815
parameters/wallslideToJump/blend_position = 0.998613
parameters/wallsliding/blend_position = 1.0
[node name="BlobbymationPlayer" type="AnimationPlayer" parent="BlobbySprite"]
@ -4697,13 +4697,13 @@ position = Vector2( 0, -1 )
[node name="Left_Wallcast1" type="RayCast2D" parent="WallRaycasts/LeftWallRaycast"]
position = Vector2( -11.9763, -5 )
enabled = true
cast_to = Vector2( -1.5, 0 )
cast_to = Vector2( -2, 0 )
collision_mask = 40
[node name="Left_Wallcast2" type="RayCast2D" parent="WallRaycasts/LeftWallRaycast"]
position = Vector2( -11.9763, 5 )
enabled = true
cast_to = Vector2( -1.5, 0 )
cast_to = Vector2( -2, 0 )
collision_mask = 40
[node name="RightWallRaycast" type="Node2D" parent="WallRaycasts"]
@ -4711,15 +4711,13 @@ collision_mask = 40
[node name="Right_Wallcast1" type="RayCast2D" parent="WallRaycasts/RightWallRaycast"]
position = Vector2( 12.0551, -5 )
enabled = true
exclude_parent = false
cast_to = Vector2( 1.5, 0 )
cast_to = Vector2( 2, 0 )
collision_mask = 40
[node name="Right_Wallcast2" type="RayCast2D" parent="WallRaycasts/RightWallRaycast"]
position = Vector2( 12.0551, 5 )
enabled = true
exclude_parent = false
cast_to = Vector2( 1.5, 0 )
cast_to = Vector2( 2, 0 )
collision_mask = 40
[node name="SlopeRaycastLeft" type="RayCast2D" parent="."]
@ -4747,11 +4745,11 @@ collision_mask = 8
script = ExtResource( 3 )
[node name="JumpBufferTimer" type="Timer" parent="BlobbyStateMachine"]
wait_time = 0.067
wait_time = 0.1
one_shot = true
[node name="CoyoteTimer" type="Timer" parent="BlobbyStateMachine"]
wait_time = 0.067
wait_time = 0.07
one_shot = true
[node name="InvincibilityTimer" type="Timer" parent="."]
@ -4765,6 +4763,7 @@ one_shot = true
[connection signal="area_entered" from="BlobbySkin" to="." method="_on_BlobbySkin_area_entered"]
[connection signal="body_entered" from="BlobbySkin" to="." method="_on_BlobbySkin_body_entered"]
[connection signal="got_grounded" from="BlobbyStateMachine" to="." method="_on_Blobby_got_grounded"]
[connection signal="timeout" from="BlobbyStateMachine/JumpBufferTimer" to="." method="_on_JumpBufferTimer_timeout"]
[connection signal="timeout" from="BlobbyStateMachine/JumpBufferTimer" to="BlobbyStateMachine" method="_on_JumpBufferTimer_timeout"]
[connection signal="timeout" from="BlobbyStateMachine/CoyoteTimer" to="BlobbyStateMachine" method="_on_CoyoteTimer_timeout"]
[connection signal="timeout" from="InvincibilityTimer" to="." method="_on_InvincibilityTimer_timeout"]
[connection signal="timeout" from="PitfallTimer" to="." method="_on_PitfallTimer_timeout"]

View File

@ -2,11 +2,8 @@ extends StateMachine
signal got_grounded
onready var coyoteTimer = $CoyoteTimer
export var coyote_hanging = false
export var init_boost = false
export var init_boost_type = ""
onready var jumpBufferTimer = $JumpBufferTimer
onready var anim_player = parent.get_node("BlobbySprite/BlobbymationPlayer")
onready var anim_state_playback = parent.get_node("BlobbySprite/AnimationTree").get("parameters/playback")
onready var anim_tree = parent.get_node("BlobbySprite/AnimationTree")
@ -15,6 +12,8 @@ onready var slope_raycast = get_node("%SlopeRaycast")
var facing = 1
var didTurn
var coyote_hanging = false
var was_coyote_hanging = false
# Adds the intial states
func _ready():
@ -33,6 +32,10 @@ func _ready():
levelState.is_dead = false
set_state(states.idle)
# Zero Vector is false
if(GlobalState.get_savepoint(levelState.levelName)):
parent.global_position = GlobalState.get_savepoint(levelState.levelName)
# Calls the parent behaviours according to state
func _state_logic(delta):
@ -79,8 +82,7 @@ func _state_logic(delta):
facing = 1
#TODO Yeah... deal with it
anim_tree.set("parameters/wallslideToJump/blend_position", parent.wall_touch_direction)
anim_tree.set("parameters/wallsliding/blend_position", parent.wall_touch_direction)
if didTurn:
_set_blendspaces_direction(facing)
_trigger_turn_animation()
@ -138,31 +140,42 @@ func _get_transition(delta):
# + String(round(parent.velocity.y / 10))
)
var new_state
print(was_coyote_hanging)
print("timer")
print($CoyoteTimer.wait_time)
if !parent.is_on_floor():
if parent.velocity.y < 0:
if parent.velocity.y < -1:
was_coyote_hanging = false
parent.jump_buffer_filled = false
new_state = states.jump
if parent.velocity.y >= 0:
# TODO SOMETHING IS SETTING Y SLIGHTLY BELOW ZERO WHEN MOVING HORIZONTALLY???
if parent.velocity.y >= -0.01:
new_state = states.fall
if parent.is_touching_wall_completely():
anim_tree.set("parameters/wallslideToJump/blend_position", parent.wall_touch_direction)
anim_tree.set("parameters/wallsliding/blend_position", parent.wall_touch_direction)
new_state = states.wallslide
# Begins coyote time only if walking from ledge
elif [states.walk, states.run].has(self.state) && !coyote_hanging:
coyoteTimer.start()
elif [states.walk, states.run].has(self.state) && !was_coyote_hanging:
$CoyoteTimer.start()
coyote_hanging = true
was_coyote_hanging = true
if new_state == states.fall && jumpBufferTimer.is_stopped():
jumpBufferTimer.start()
if new_state == states.fall && $JumpBufferTimer.is_stopped():
$JumpBufferTimer.start()
# It's important to check this here and not set by event (order)
if (
coyoteTimer.is_stopped()
$CoyoteTimer.is_stopped()
|| [states.idle, states.jump].has(self.state)
):
coyote_hanging = false
if coyote_hanging:
new_state = self.state
elif abs(parent.velocity.x) > 5:
was_coyote_hanging = false
if Input.is_action_pressed("boost_move"):
new_state = states.run
# TODO Walking when stopping and not pressing anything?
@ -170,13 +183,13 @@ func _get_transition(delta):
new_state = states.walk
if Input.is_action_pressed("duck"):
new_state = states.duck
coyote_hanging = false
else:
was_coyote_hanging = false
new_state = states.idle
if Input.is_action_pressed("duck"):
new_state = states.duck
coyote_hanging = false
if new_state != self.state:
state_time = 0
return new_state
@ -244,4 +257,6 @@ func _trigger_turn_animation():
anim_state_playback.travel("idleTurn")
states.idle:
anim_state_playback.travel("idleTurn")
func _on_JumpBufferTimer_timeout() -> void:
parent.jump_buffer_filled = false

View File

@ -44,7 +44,10 @@ unique_name_in_owner = true
drag_margin_bottom = 0.3
[node name="AnimatedSprite" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="4"]
frame = 12
frame = 1
[node name="AnimatedSprite2" parent="BlobbyCam/ParallaxBackground/ParallaxLayer5" index="5"]
frame = 1
[node name="Blobby" parent="." instance=ExtResource( 9 )]
unique_name_in_owner = true

View File

@ -50,6 +50,13 @@ position = Vector2( 63, 336 )
[node name="AnimationTree" parent="Blobby/BlobbySprite" index="0"]
parameters/playback = SubResource( 4 )
[node name="JumpBufferTimer" parent="Blobby/BlobbyStateMachine" index="0"]
process_mode = 0
wait_time = 0.605
[node name="CoyoteTimer" parent="Blobby/BlobbyStateMachine" index="1"]
process_mode = 0
[node name="Portal" parent="." instance=ExtResource( 41 )]
position = Vector2( 745, 312 )
next_scene = ExtResource( 1 )

View File

@ -219,6 +219,7 @@ frame = 6
[node name="Blobby" parent="." instance=ExtResource( 8 )]
unique_name_in_owner = true
position = Vector2( 924, -483 )
[node name="AnimationTree" parent="Blobby/BlobbySprite" index="0"]
parameters/playback = SubResource( 4 )