Skip to content

Commit 3dce3a1

Browse files
authored
Merge pull request #6 from endlessm/player-physics-improvements
Player physics improvements
2 parents 5b5b8ef + 20f1ae4 commit 3dce3a1

File tree

3 files changed

+91
-8
lines changed

3 files changed

+91
-8
lines changed

components/enemy/enemy.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func _on_gravity_changed(new_gravity):
7171
func _on_hitbox_body_entered(body):
7272
if body.name == "Player":
7373
if squashable and body.velocity.y > 0 and body.position.y < position.y:
74-
body.velocity.y = body.jump_velocity
74+
body.stomp()
7575
queue_free()
7676
elif player_loses_life:
7777
Global.lives -= 1

components/player/player.tscn

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ floor_constant_speed = true
1414
floor_snap_length = 32.0
1515
script = ExtResource("1_w3ms2")
1616

17+
[node name="DoubleJumpParticles" type="CPUParticles2D" parent="."]
18+
unique_name_in_owner = true
19+
emitting = false
20+
amount = 60
21+
lifetime = 0.2
22+
one_shot = true
23+
explosiveness = 0.54
24+
randomness = 0.25
25+
emission_shape = 1
26+
emission_sphere_radius = 36.72
27+
particle_flag_align_y = true
28+
gravity = Vector2(0, 1)
29+
scale_amount_max = 5.0
30+
color = Color(1, 1, 0, 1)
31+
1732
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
1833
unique_name_in_owner = true
1934
position = Vector2(0, -64)

scripts/player.gd

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,47 @@ extends CharacterBody2D
99
@export_range(0, 1000, 10, "suffix:px/s") var speed: float = 500.0:
1010
set = _set_speed
1111

12+
## How fast does your character accelerate?
13+
@export_range(0, 5000, 1000, "suffix:px/s²") var acceleration: float = 5000.0
14+
1215
## How high does your character jump? Note that the gravity will
1316
## be influenced by the [member GameLogic.gravity].
1417
@export_range(-1000, 1000, 10, "suffix:px/s") var jump_velocity = -880.0
1518

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+
1646
# Get the gravity from the project settings to be synced with RigidBody nodes.
1747
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
1848
var original_position: Vector2
1949

2050
@onready var _sprite: AnimatedSprite2D = %AnimatedSprite2D
2151
@onready var _initial_sprite_frames: SpriteFrames = %AnimatedSprite2D.sprite_frames
52+
@onready var _double_jump_particles: CPUParticles2D = %DoubleJumpParticles
2253

2354

2455
func _set_sprite_frames(new_sprite_frames):
@@ -55,26 +86,58 @@ func _on_gravity_changed(new_gravity):
5586
gravity = new_gravity
5687

5788

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+
58105
func _physics_process(delta):
59106
# Don't move if there are no lives left.
60107
if Global.lives <= 0:
61108
return
62109

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+
63126
# Add the gravity.
64-
if not is_on_floor():
127+
if coyote_timer <= 0:
65128
velocity.y += gravity * delta
66129

67-
# Handle jump.
68-
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
69-
velocity.y = jump_velocity
70-
71130
# Get the input direction and handle the movement/deceleration.
72131
# As good practice, you should replace UI actions with custom gameplay actions.
73132
var direction = Input.get_axis("ui_left", "ui_right")
74133
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+
)
76139
else:
77-
velocity.x = move_toward(velocity.x, 0, speed)
140+
velocity.x = move_toward(velocity.x, 0, acceleration * delta)
78141

79142
if velocity == Vector2.ZERO:
80143
_sprite.play("idle")
@@ -90,10 +153,15 @@ func _physics_process(delta):
90153

91154
move_and_slide()
92155

156+
coyote_timer -= delta
157+
jump_buffer_timer -= delta
158+
93159

94160
func reset():
95161
position = original_position
96162
velocity = Vector2.ZERO
163+
coyote_timer = 0
164+
jump_buffer_timer = 0
97165

98166

99167
func _on_lives_changed():

0 commit comments

Comments
 (0)