TJRC
TJRC

Reputation: 434

How do I make sure only 1 instance of a specified Sound is looping and how do I stop it from looping?

I am currently working on a game and in the player update method, I want a footstep Sound to start looping when the player walks and I want it to stop looping when the player stops walking. However, I'm having trouble figuring out how I make can sure that only 1 instance of the Sound is looping.

For clarification: I'm talking about the gdx.audio.Sound class. This is what my code currently looks like:

//Sets the footstep sound. i.e. it changes to a grass soundfile when you walk on grass.
String footstepsFilePath = gameMap.getTileSoundFilePath(rect);
setFootsteps(Gdx.audio.newSound(Gdx.files.internal(footstepsFilePath)));

//velocity is the speed at which the player is going in the x or y direction.
if(velocity.y != 0 || velocity.x != 0) footsteps.loop();
if(velocity.y == 0 && velocity.x == 0) footsteps.stop();

Result: As soon as the player starts moving, a ton of instances of the footsteps sound start looping. When the player stops moving, all of them continue looping. The first part is for obvious reasons, but I can't figure out how I can make sure that only 1 instance is looping. But for the second part, I'm not sure why not all instances of footsteps stop looping, because this is what the documentation on stop() says:

Stops playing all instances of this sound.

Upvotes: 0

Views: 72

Answers (1)

Mad Physicist
Mad Physicist

Reputation: 114488

Assuming that you check if(velocity.y != 0 || velocity.x != 0) frequently, you will indeed kick off many loops. The trick is to check "is the player moving, and were they still last time I looked?" rather than just "is the player moving".

A simple way is to set a boolean flag:

//Sets the footstep sound. i.e. it changes to a grass soundfile when you walk on grass.
String footstepsFilePath = gameMap.getTileSoundFilePath(rect);
setFootsteps(Gdx.audio.newSound(Gdx.files.internal(footstepsFilePath)));

boolean isMoving = false;

//velocity is the speed at which the player is going in the x or y direction.
if((velocity.y != 0 || velocity.x != 0) && !isMoving) {
    isMoving = true;
    footsteps.loop();
}

if((velocity.y == 0 && velocity.x == 0) && isMoving) {
    footsteps.stop();
    isMoving = false;
}

I am not entirely certain why stop does not work in your case. However, the documentation for the other two loop overloads states

You need to stop the sound via a call to stop(long) using the returned id.

Perhaps the version of stop you are using doesn't work, or perhaps it waits for the current loop to finish?

Upvotes: 1

Related Questions