0 votes

Hello, I want to play a footstep sound when the character is moving.
Here is my character controller script:

extends KinematicBody2D

const GRAVITY = 20
const MAX_SPEED = 200
const JUMP_HEIGHT = -600
const ACCELERATION = 30
const UP = Vector2(0, -1)
var motion = Vector2()
var is_crouching = false

func _ready():
    $Crickets.play()

func _physics_process(delta):
    motion.y += GRAVITY
    var friction = false

    if Input.is_action_pressed("ui_right"):
        if not is_crouching:
            motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
            $Sprite.flip_h = false
            $Sprite.play("Run")
        else:
            motion.x = min(motion.x+ACCELERATION, MAX_SPEED/2)
            $Sprite.flip_h = false
            $Sprite.play("CrouchingWalk")
    elif Input.is_action_pressed("ui_left"):
        if not is_crouching:
            motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
            $Sprite.flip_h = true
            $Sprite.play("Run")
        else:
            motion.x = max(motion.x-ACCELERATION, -MAX_SPEED/2)
            $Sprite.flip_h = true
            $Sprite.play("CrouchingWalk")
    else:
        if not is_crouching:
            $Sprite.play("Idle")
        else:
            $Sprite.play("Crouching")
        friction = true

    if is_on_floor():
        if Input.is_action_just_pressed("ui_down"):
            is_crouching = true
            $CollShapeTop.disabled = true
            $Sprite.play("Crouching")
        elif Input.is_action_just_pressed("ui_up"):
            if not is_crouching:
                motion.y = JUMP_HEIGHT
            else:
                is_crouching = false
                $CollShapeTop.disabled = false
                $Sprite.play("Idle")
        if friction == true:
            motion.x = lerp(motion.x, 0, 0.9)

            # I want to play the sound when character is on the floor and moving on the ground, not jumping.
        if motion.x >= 1 || motion.x <= -1:
            $Footstep.play()
        else:
            $Footstep.stop()
    else:
        if motion.y < 0:
            $Sprite.play("Jump")
        else:
            $Sprite.play("Fall")
        if friction == true:
            motion.x = lerp(motion.x, 0, 0.05)
    motion = move_and_slide(motion, UP)

The problem is that when I press the arrow keys sound starts to playing, but not the whole sound... It starting over and over again... $Footstep is a AudioStreamPlayer2D with a footstep sound(47s ogg file).

asked May 7, 2019 in Engine by markbatho (18 points)
edited May 7, 2019 by markbatho

1 Answer

+1 vote

Okay, I played a little with the code...
This is the modified version:

extends KinematicBody2D

const GRAVITY = 20
const MAX_SPEED = 200
const JUMP_HEIGHT = -600
const ACCELERATION = 30
const UP = Vector2(0, -1)
var motion = Vector2()
var is_crouching = false

func _ready():
    $Crickets.play()

func _physics_process(delta):
    motion.y += GRAVITY
    var friction = false

    if Input.is_action_pressed("ui_right"):
            # Here is the sound, played when player is on the ground:
        if is_on_floor():
            if not $Footstep.is_playing():
                $Footstep.play()
        if not is_crouching:
            motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
            $Sprite.flip_h = false
            $Sprite.play("Run")
        else:
            motion.x = min(motion.x+ACCELERATION, MAX_SPEED/2)
            $Sprite.flip_h = false
            $Sprite.play("CrouchingWalk")
    elif Input.is_action_pressed("ui_left"):
            # Here is the sound, played when player is on the ground:
        if is_on_floor():
            if not $Footstep.is_playing():
                $Footstep.play()
        if not is_crouching:
            motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
            $Sprite.flip_h = true
            $Sprite.play("Run")
        else:
            motion.x = max(motion.x-ACCELERATION, -MAX_SPEED/2)
            $Sprite.flip_h = true
            $Sprite.play("CrouchingWalk")
    else:
            # Stop when player is idle so not moving
        $Footstep.stop()
        if not is_crouching:
            $Sprite.play("Idle")
        else:
            $Sprite.play("Crouching")
        friction = true

    if is_on_floor():
        if Input.is_action_just_pressed("ui_down"):
            is_crouching = true
            $CollShapeTop.disabled = true
            $Sprite.play("Crouching")
        elif Input.is_action_just_pressed("ui_up"):
                    # And play the jumping sound:
            if $Footstep.is_playing():
                $Footstep.stop()
            if not is_crouching:
                $Jump.play()
                motion.y = JUMP_HEIGHT
            else:
                is_crouching = false
                $CollShapeTop.disabled = false
                $Sprite.play("Idle")
        if friction == true:
            motion.x = lerp(motion.x, 0, 0.9)
    else:
        if motion.y < 0:
            $Sprite.play("Jump")
        else:
            $Sprite.play("Fall")
        if friction == true:
            motion.x = lerp(motion.x, 0, 0.05)
    motion = move_and_slide(motion, UP)
answered May 7, 2019 by markbatho (18 points)

Any idea for play a sound when the player is in the aire (when jump) and touch the floor? Can you use the above script.

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.