trigger an event on landing

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Limbaz

Hi,
i just started out with godot. The code is for testing and learning the engine.
I struggle to figure out how to trigger an event if the player lands on the ground.
The first thing i want is to play a landing sound.
I did some research and tried the suggestions, but the result is always the same, the sound is played at the beginning of the jump or is repeatedly played while the player is on the ground.

I also tried to make a solution with connection of animation finished:

if is_on_gound() and animation_finished("jump"):
    $LandSound.play()

but it also didn’t work

extends KinematicBody2D

export (int) var walk_speed = 150
export (int) var run_speed = 300
export (int) var jump_speed = -400
export (int) var gravity = 1200

var velocity = Vector2()

enum {IDLE, IDLELEFT, WALK, RUNNING}
enum {LEFT, RIGHT}
var facing
var state
var anim
var new_anim
var jumping = false
var walking = false
var running = false
var current_speed

func change_state(new_state):
	state = new_state
	match state:
		IDLE:
			new_anim = 'Idle'
		IDLELEFT:
			new_anim = 'IdleLeft'
		WALK:
			new_anim = 'Walk'
		RUNNING:
			new_anim = 'RunningRight'


func get_input():
	velocity.x = 0
	var left = Input.is_action_pressed("ui_left")
	var right = Input.is_action_pressed("ui_right")
	var jump = Input.is_action_pressed("ui_select")
	var run = Input.is_action_pressed("ui_run")
	
	if left or right:
		current_speed = walk_speed
		walking = true
	else:
		walking = false
	if (left or right) and run:
		current_speed = run_speed
		running = true
	else:
		running = false
	
	if left:
		$AnimatedSprite.flip_h = true
		velocity.x -= current_speed
		if is_on_floor():
			if walking:
				change_state(WALK)
			if running:
				change_state(RUNNING)
			$AnimationPlayer.play(new_anim)
		facing = LEFT
	if right:
		$AnimatedSprite.flip_h = false
		velocity.x += current_speed
		if is_on_floor():
			if walking:
				change_state(WALK)
			if running:
				change_state(RUNNING)
			$AnimationPlayer.play(new_anim)
		facing = RIGHT
	
	if velocity.x == 0 and is_on_floor():
		if facing == RIGHT:
			change_state(IDLE)
			$AnimationPlayer.play(new_anim)
		else:
			change_state(IDLELEFT)
			$AnimationPlayer.play(new_anim)
	if running:
		if jump and is_on_floor():
			jumping = true
			velocity.y = jump_speed

func _process(delta):
	if position.y > 1000:
		position.y = 0

func _physics_process(delta):
	get_input()
	velocity.y += gravity * delta
	if jumping and is_on_floor():
		$AnimationPlayer.play("Jump")
		jumping = false

	velocity = move_and_slide(velocity, Vector2(0, -1))

Fixed a problem because of this question. THANK YOU!

GamersPointeGames | 2020-03-02 06:31

:bust_in_silhouette: Reply From: Magso

Here’s a work around I’ve used before. It basically a bool that checks if it’s only just landed.

var landing : bool

if is_on_floor():
    if landing:
        $LandSound.play()
        landing = false
else:
    if !landing:
        landing = true

Just to add for anyone who might not understand the else part.

else: # In the air 
    if !landing: # In the air and haven't landed
        landing = true

AirWick | 2022-08-27 20:24