• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker How do I make a sound play once (and continue to play), without playing multiple instances of the same sound while a key is held?

L

lukeman3000

Guest
I'm following along with the Space Rocks tutorial and wanted to add a jet booster to the ship, along with a propulsion sound effect.

I got the sprite animation figured out, and the sound (to some degree). However, the problem is that while "w" is held, it doesn't just play the sound effect - it seems to start playing it repeatedly (I assume 60 new times per second, as per the step function).

So, how do I just make it start playing within a singular instance of the sound effect while the key is held, instead (and thus stop playing when the key is released)?

GML:
if (keyboard_check(ord("W"))){
    motion_add(image_angle, 0.05);
    image_index = 1;
    audio_play_sound(Ship_Jet, 1, false);
} else {
    image_index = 0;
    audio_stop_sound(Ship_Jet);
}
 

Roldy

Member
I'm following along with the Space Rocks tutorial and wanted to add a jet booster to the ship, along with a propulsion sound effect.

I got the sprite animation figured out, and the sound (to some degree). However, the problem is that while "w" is held, it doesn't just play the sound effect - it seems to start playing it repeatedly (I assume 60 new times per second, as per the step function).

So, how do I just make it start playing within a singular instance of the sound effect while the key is held, instead (and thus stop playing when the key is released)?

GML:
if (keyboard_check(ord("W"))){
    motion_add(image_angle, 0.05);
    image_index = 1;
    audio_play_sound(Ship_Jet, 1, false);
} else {
    image_index = 0;
    audio_stop_sound(Ship_Jet);
}
Try when the key is pressed check if the sound is playing, if not then start it looping, and then when the key is released stop the sound. That would continue to play the sound while the key is pressed and stop it when you release the key.
 
L

lukeman3000

Guest
Try when the key is pressed check if the sound is playing, if not then start it looping, and then when the key is released stop the sound. That would continue to play the sound while the key is pressed and stop it when you release the key.
I'm afraid I don't entirely understand - could you show me what you mean with a code example?

If you do the check and the sound *is* playing, what should you do? Just leave that section of the if statement blank?

Edit: Pretty sure I got it working, thanks to your suggestion:

GML:
if (keyboard_check(ord("W")))
{
    motion_add(image_angle, 0.05);
    image_index = 1;
    if audio_is_playing(Ship_Jet)
    {
    }
    else
    {
        audio_play_sound(Ship_Jet, 1, true);
    }
}
 
Last edited by a moderator:

Roldy

Member
I'm afraid I don't entirely understand - could you show me what you mean with a code example?

If you do the check and the sound *is* playing, what should you do? Just leave that section of the if statement blank?

Edit: Pretty sure I got it working, thanks to your suggestion:

GML:
if (keyboard_check(ord("W")))
{
    motion_add(image_angle, 0.05);
    image_index = 1;
    if audio_is_playing(Ship_Jet)
    {
    }
    else
    {
        audio_play_sound(Ship_Jet, 1, true);
    }
}

Nice, good job. But if you want to make it a little nicer and readable, just make your 'if' statement check that it is NOT playing and remove the 'else.'

Here are three different ways to write what you already have but a little cleaner.
All three (and your code too) will produce the same compiled code. But I think the examples below are more readable.

GML:
if (keyboard_check(ord("W")))
{
    motion_add(image_angle, 0.05);
    image_index = 1;

   // using the '!' operator. i.e. If not audio_is_playing
    if ( ! audio_is_playing(Ship_Jet) )  {
        audio_play_sound(Ship_Jet, 1, true);
    }

}
or you could write:

GML:
if (keyboard_check(ord("W")))
{
    motion_add(image_angle, 0.05);
    image_index = 1;

   // using the '!=' operator.  i.e. If audio_is_playing is not true
    if ( audio_is_playing(Ship_Jet) != true)  {
        audio_play_sound(Ship_Jet, 1, true);
    }
}
or

GML:
if (keyboard_check(ord("W")))
{
    motion_add(image_angle, 0.05);
    image_index = 1;

    // using the '==' operator.  i.e.  If audio_is_playing is false.
    if ( audio_is_playing(Ship_Jet) == false)  {
        audio_play_sound(Ship_Jet, 1, true);
    }
}
 
Last edited:
L

lukeman3000

Guest
Thank you for that. That does make a lot more sense to test for false; I didn't think of that. Nor was I aware you could use an operator in that way.

I am curious, is there a reason as to why you changed the bracket structure on the second if statement? That is, after the first if statement your brackets have lines to themselves, and after the second if statement, you put the first bracket on the same line as the if statement.

To my knowledge it doesn't matter, but I'm wondering is there a particular reason you did it this way as opposed to given that other bracket its own line? For example, I would probably prefer it to look this way, unless there is a reason I should consider otherwise:

GML:
if (keyboard_check(ord("W")))
{
    motion_add(image_angle, 0.05);
    image_index = 1;

    // using the '==' operator.  i.e.  If audio_is_playing is false.
    if ( audio_is_playing(Ship_Jet) == false)
    {
        audio_play_sound(Ship_Jet, 1, true);
    }
}
 

Sedgwick2K

Member
You can also assign the sound effect at Create event, then set the volume as 0, then the propulsion key would adjust its volume.
(I was doing that while making drag racing games back then :D )
 
Just to add another layer of possibility here, you can also use the ! operator like this:
Code:
if (!audio_is_playing(Ship_Jet)) {
   audio_play_sound(Ship_Jet,1,true);
}
Reading that aloud in english would basically be "If not audio is playing: Ship_Jet then..." or in other words, if audio_is_playing returns false, then that conditional check is true (which is more convoluted than the plain english, but is a little more technically correct).
 

Roldy

Member
Thank you for that. That does make a lot more sense to test for false; I didn't think of that. Nor was I aware you could use an operator in that way.

I am curious, is there a reason as to why you changed the bracket structure on the second if statement? That is, after the first if statement your brackets have lines to themselves, and after the second if statement, you put the first bracket on the same line as the if statement.

To my knowledge it doesn't matter, but I'm wondering is there a particular reason you did it this way as opposed to given that other bracket its own line? For example, I would probably prefer it to look this way, unless there is a reason I should consider otherwise:

GML:
if (keyboard_check(ord("W")))
{
    motion_add(image_angle, 0.05);
    image_index = 1;

    // using the '==' operator.  i.e.  If audio_is_playing is false.
    if ( audio_is_playing(Ship_Jet) == false)
    {
        audio_play_sound(Ship_Jet, 1, true);
    }
}

You are right it, it is just a style and personal preference. Where I put the brackets for 'if' statements is from ingrained habit. It was the official style guide for my company that I worked for more than a decade, so I tend to default to it.

But it is no better or worse than any other style. If you like putting the brackets on their own lines that is up to you in your own code.

The important thing about formatting styles is to be consistent through out. Pick one, adhere to one and start typing.
 

Yal

šŸ§ *penguin noises*
GMC Elder
You are right it, it is just a style and personal preference. Where I put the brackets for 'if' statements is from ingrained habit. It was the official style guide for my company that I worked for more than a decade, so I tend to default to it.

But it is no better or worse than any other style. If you like putting the brackets on their own lines that is up to you in your own code.

The important thing about formatting styles is to be consistent through out. Pick one, adhere to one and start typing.
To add to this, essentially all whitespace is optional. (There's a few exceptions, like having to separate words with at least one space for them to count as two separate "tokens" - "for x" is separate from "forx"). You can do whatever you want with it, and people have fought long and bloody battles over things like whether to use tabs or spaces to indent code blocks, and how wide indentations should be.
 
Top