@@ -9,16 +9,47 @@ extends CharacterBody2D
9
9
@export_range (0 , 1000 , 10 , "suffix:px/s" ) var speed : float = 500.0 :
10
10
set = _set_speed
11
11
12
+ ## How fast does your character accelerate?
13
+ @export_range (0 , 5000 , 1000 , "suffix:px/s²" ) var acceleration : float = 5000.0
14
+
12
15
## How high does your character jump? Note that the gravity will
13
16
## be influenced by the [member GameLogic.gravity].
14
17
@export_range (- 1000 , 1000 , 10 , "suffix:px/s" ) var jump_velocity = - 880.0
15
18
19
+ ## How much should the character's jump be reduced if you let go of the jump
20
+ ## key before the top of the jump? [code]0[/code] means “not at all”;
21
+ ## [code]100[/code] means “upwards movement completely stops”.
22
+ @export_range (0 , 100 , 5 , "suffix:%" ) var jump_cut_factor : float = 20
23
+
24
+ ## How long after the character walks off a ledge can they still jump?
25
+ ## This is often set to a small positive number to allow the player a little
26
+ ## margin for error before they start falling.
27
+ @export_range (0 , 0.5 , 1 / 60.0 , "suffix:s" ) var coyote_time : float = 5.0 / 60.0
28
+
29
+ ## If the character is about to land on the floor, how early can the player
30
+ ## the jump key to jump as soon as the character lands? This is often set to
31
+ ## a small positive number to allow the player a little margin for error.
32
+ @export_range (0 , 0.5 , 1 / 60.0 , "suffix:s" ) var jump_buffer : float = 5.0 / 60.0
33
+
34
+ ## Can your character jump a second time while still in the air?
35
+ @export var double_jump : bool = false
36
+
37
+ # If positive, the player is either on the ground, or left the ground less than this long ago
38
+ var coyote_timer : float = 0
39
+
40
+ # If positive, the player pressed jump this long ago
41
+ var jump_buffer_timer : float = 0
42
+
43
+ # If true, the player is already jumping and can perform a double-jump
44
+ var double_jump_armed : bool = false
45
+
16
46
# Get the gravity from the project settings to be synced with RigidBody nodes.
17
47
var gravity = ProjectSettings .get_setting ("physics/2d/default_gravity" )
18
48
var original_position : Vector2
19
49
20
50
@onready var _sprite : AnimatedSprite2D = % AnimatedSprite2D
21
51
@onready var _initial_sprite_frames : SpriteFrames = % AnimatedSprite2D .sprite_frames
52
+ @onready var _double_jump_particles : CPUParticles2D = % DoubleJumpParticles
22
53
23
54
24
55
func _set_sprite_frames (new_sprite_frames ):
@@ -55,26 +86,58 @@ func _on_gravity_changed(new_gravity):
55
86
gravity = new_gravity
56
87
57
88
89
+ func _jump ():
90
+ velocity .y = jump_velocity
91
+ coyote_timer = 0
92
+ jump_buffer_timer = 0
93
+ if double_jump_armed :
94
+ double_jump_armed = false
95
+ _double_jump_particles .emitting = true
96
+ elif double_jump :
97
+ double_jump_armed = true
98
+
99
+
100
+ func stomp ():
101
+ double_jump_armed = false
102
+ _jump ()
103
+
104
+
58
105
func _physics_process (delta ):
59
106
# Don't move if there are no lives left.
60
107
if Global .lives <= 0 :
61
108
return
62
109
110
+ # Handle jump
111
+ if is_on_floor ():
112
+ coyote_timer = (coyote_time + delta )
113
+ double_jump_armed = false
114
+
115
+ if Input .is_action_just_pressed ("ui_accept" ):
116
+ jump_buffer_timer = (jump_buffer + delta )
117
+
118
+ if jump_buffer_timer > 0 and (double_jump_armed or coyote_timer > 0 ):
119
+ _jump ()
120
+
121
+ # Reduce velocity if the player lets go of the jump key before the apex.
122
+ # This allows controlling the height of the jump.
123
+ if Input .is_action_just_released ("ui_accept" ) and velocity .y < 0 :
124
+ velocity .y *= (1 - (jump_cut_factor / 100.00 ))
125
+
63
126
# Add the gravity.
64
- if not is_on_floor () :
127
+ if coyote_timer <= 0 :
65
128
velocity .y += gravity * delta
66
129
67
- # Handle jump.
68
- if Input .is_action_just_pressed ("ui_accept" ) and is_on_floor ():
69
- velocity .y = jump_velocity
70
-
71
130
# Get the input direction and handle the movement/deceleration.
72
131
# As good practice, you should replace UI actions with custom gameplay actions.
73
132
var direction = Input .get_axis ("ui_left" , "ui_right" )
74
133
if direction :
75
- velocity .x = direction * speed
134
+ velocity .x = move_toward (
135
+ velocity .x ,
136
+ sign (direction ) * speed ,
137
+ abs (direction ) * acceleration * delta ,
138
+ )
76
139
else :
77
- velocity .x = move_toward (velocity .x , 0 , speed )
140
+ velocity .x = move_toward (velocity .x , 0 , acceleration * delta )
78
141
79
142
if velocity == Vector2 .ZERO :
80
143
_sprite .play ("idle" )
@@ -90,10 +153,15 @@ func _physics_process(delta):
90
153
91
154
move_and_slide ()
92
155
156
+ coyote_timer -= delta
157
+ jump_buffer_timer -= delta
158
+
93
159
94
160
func reset ():
95
161
position = original_position
96
162
velocity = Vector2 .ZERO
163
+ coyote_timer = 0
164
+ jump_buffer_timer = 0
97
165
98
166
99
167
func _on_lives_changed ():
0 commit comments