Godot Version
4.5.1
Question
I’m loving the Beat ‘Em Up Tutorial series by The Game Dev Tavern, but I ran into an issue with the player jump mechanic that I can’t figure out - when I jump, the player never lands back down where they started. The shadow and collision shapes don’t move, as would be expected, but the sprite keeps inching up the y axis. From what I can tell from some simple print() debugging, I’m landing at a height of 7.875 instead of 0. But I AM landing, but it means that the sprite never “rejoins” it’s shadow and collision shapes, and each subsequent jump pulls it further and further up the y axis.
Any ideas?
Can you share the code of the jump mechanic?
extends CharacterBody2D
const GRAVITY := 600.0
@export var damage : int
@export var health : int
@export var jump_intensity : float
@export var speed : float
@onready var animation_player := $AnimationPlayer
@onready var character_sprite := $CharacterSprite
@onready var damage_emitter := $DamageEmitter
enum State {IDLE, WALK, ATTACK, TAKEOFF, JUMP, LAND}
var anim_map := {
State.IDLE: “idle”,
State.WALK: “walk”,
State.ATTACK: “punch”,
State.TAKEOFF: “takeoff”,
State.JUMP: “jump”,
State.LAND: “land”,
}
var height := 0.0
var height_speed := 0.0
var state = State.IDLE
func _ready() → void:
damage_emitter.area_entered.connect(on_emit_damage.bind())
func _process(delta: float) → void:
handle_input()
handle_movement()
handle_animations()
handle_air_time(delta)
flip_sprites()
character_sprite.position = Vector2.UP * height
move_and_slide()
func handle_movement() → void:
if can_move():
if velocity.length() == 0:
state = State.IDLE
else:
state = State.WALK
else:
velocity = Vector2.ZERO
func handle_input() → void:
var direction := Input.get_vector(“ui_left”, “ui_right”, “ui_up”, “ui_down”)
velocity = direction * speed
if can_attack() and Input.is_action_just_pressed(“attack”):
state = State.ATTACK
if can_jump() and Input.is_action_just_pressed(“jump”):
state = State.TAKEOFF
print("jumped ", “starting height:”, height)
func handle_animations() → void:
if animation_player.has_animation(anim_map[state]):
animation_player.play(anim_map[state])
func handle_air_time(delta: float) → void:
if state == State.JUMP:
height += height_speed * delta
if height < 0:
height = 0
state = State.LAND
print(“landed”)
else:
print(“falling”)
height_speed -= GRAVITY * delta
print(height)
func flip_sprites() → void:
if velocity.x > 0:
character_sprite.flip_h = false
damage_emitter.scale.x = 1
elif velocity.x < 0:
character_sprite.flip_h = true
damage_emitter.scale.x = -1
func can_move() → bool:
return state == State.IDLE or state == State.WALK
func can_attack() → bool:
return state == State.IDLE or state == State.WALK
func on_action_complete() → void:
state = State.IDLE
func on_takeoff_complete() → void:
state = State.JUMP
height_speed = jump_intensity
print(“takeoff completed”)
func on_land_complete() → void:
state = State.IDLE
print(“land completed”)
func on_emit_damage(damage_receiver: DamageReceiver) → void:
var direction := Vector2.LEFT if damage_receiver.global_position.x < global_position.x else Vector2.RIGHT
damage_receiver.damage_received.emit(damage, direction)
print(damage_receiver)
func can_jump() → bool:
return state == State.IDLE or state == State.WALK
It looks like your height_speed is set to 0, therefore you wont gain any height and since you are working on a 2d sidescroller the gravity should either be added(not subtracted) to your height_speed or the gravity value has to be negative, because in godot -Y is up and +Y is down
Edit:
Sorry your height_speed is getting set to “jump_intensity”, what value does jump_intensity have in your scene?
Can you print the “height”-property in the “on_land_complete”-method and tell me whats the value
Sure thing!
jumped starting height:0.0
takeoff completed
falling
0.83333333333333
falling
1.625
falling
2.375
falling
3.08333333333333
falling
3.75
falling
4.375
falling
4.95833333333333
falling
5.5
falling
6.0
falling
6.45833333333333
falling
6.875
falling
7.25
falling
7.58333333333333
falling
7.875
*LAND COMPLETED HEIGHT:7.875
Fixed it myself by going back through the video. I had an issue with my animation player the method callbacks. Thanks!
1 Like