+1 vote

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))
asked Feb 28 in Engine by Limbaz (13 points)

Fixed a problem because of this question. THANK YOU!

1 Answer

+2 votes

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
answered Feb 28 by Magso (2,867 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.