game-makersoundeffect

Game Maker Turn On/Off Sound Effects


I'm making a game, which has a setting to turn on/off all sfx. I have these sfx: snd_hover, snd_click, and snd_back. These sfx are automatically played from the home screen. I have tried these function:

audio_exists
audio_stop_all

but all sfx are still playing. I have tried to make:

a variable which turn into 0 when btn_Off is clicked,
and turn into 1 when btn_On is clicked

but all sfx are still playing. What should I do? Please give drag-event answers if possible.


Solution

  • Usually I do something like this:

    /// play_sound(sound, [loop])
    
    var vol = global.volume_sfx;    // global.volume_sfx must contain volume (0...1)
    if vol == 0 exit;               // if volume is 0 then not need play, exit
    
    var snd = argument[0];          // name of sound which need play, passed to the script
    var loop = false;               // need loop sound or not
    if argument_count > 1 loop = argument[1];
    
    var s = audio_play_sound(snd, 50, loop);  // Start sound
    audio_sound_gain(s, vol, 0);    // Set volume for this sound
    

    Usage:

    play_sound(snd_click, false);
    

    When I need stop all sounds, I do:

    audio_stop_all();
    

    upd: Create new script with name play_sound with first code. Then call it when you need play any sound. This code gets volume from settings (var vol = global.volume_sfx) and plays all sounds with this volume.

    Variable global.volume_sfx must contain value from 0 (no sound) to 1 (full volume). So, for enable/disable sounds you need change this variable from 0 to 1 or from 1 to 0 (like global.volume_sfx = !global.volume_sfx). Or if you have slider in sound preferences then you can set any volume (for example, 0.5 for 50% of maximum volume).

    See small example with slider and sound on/off button.

    upd2:

    Sorry, but I still don't understand your code. Can you explain the script and obj_sound_enable for each row?

    My English is bad, but I'll try...

    Well. Let's imagine that there is a menu where the user can adjust the sound volume. Any playing of a sound in game shall consider this setup. This can be done in many ways.

    For example, possible to create different audio groups - one for music, one for effects and set the volume to a whole group. In this case all sounds will be stored in memory that approaches not always (audio groups do not work for stream playing).

    Other method - to change the global level of volume. Simply, but doesn't approach if it is necessary to make separate settings for music and effects.

    Another way (that I've suggested) - create your own function that will be used to play sounds. To the function, must be passed the name of the sound you want to play and the option whether the sound is looped or not. Function checks settings of volume and plays a sound according to them.

    /// play_sound(sound, [loop])
    

    This line defines the hint which will be showed in code editor. Square brackets usually indicate a parameter that can be skipped. I.e. the function can be called with a single parameter or two:

    play_sound(snd_wind, true);  // play sound snd_wind with loop
    play_sound(snd_explode);     // play sound snd_explode (no loop)
    

    Next line.

    var vol = global.volume_sfx;    // global.volume_sfx must contain volume (0...1)
    

    global.volume_sfx is a global variable, which contains volume. It is set by the user in the settings of the game. This should be a value from 0 (no sound) to 1 (full volume).

    vol is a variable that will be used for temporary storage volume settings. Of course, we can use global.volume_sfx instead, rather than create a new variable, but I prefer local variables for some reasons. First of them - local variables work a little faster than global variables. Second - if you need to change global.volume_sfx to something else, you will need to change it only in one place - this reduces the probability of errors/typos/etc.

    The var keyword indicates that this is a local variable, and this variable will be destroyed after the script is finished.

    if (vol == 0) exit;             // if volume is 0 then not need play, exit
    

    vol variable already contains the volume level and here this value is checked. If the volume level is equal to zero (if vol == 0), it is not necessary to play the sound and the script will be terminated (exit).

    var snd = argument[0];          // name of sound which need to be played, passed to the script
    

    Here the local variable snd is created. It will contain the first parameter which was passed to a script (numbering starts from zero). And this parameter contains the name of the sound you want to play.

    var loop = false;               // need loop sound or not
    

    The loop variable will show, must be a sound looped, or not. By default value will be false, i.e. sound isn't looped.

    if (argument_count > 1) loop = argument[1];
    

    It checks, how many arguments passed to the script. If more than one (argument_count > 1) then loop variable will be assigned the value of the second argument (loop = argument[1])

    var s = audio_play_sound(snd, 50, loop);  // Start sound
    

    It plays sound with priority 50. Variable s will contain result of this operation, and it will be special id, which can be used later for control this (exactly this, and no any other) sound. Next line will use it for set right volume.

    audio_sound_gain(s, vol, 0);    // Set volume for this sound
    

    This function sets the specified sound to the necessary volume.

    You can look at the detailed description of functions in GMS documentation.

    In simplest case this script looks like this:

    /// play_sound(sound, is_loop)
    
    if (global.volume_sfx == 0) exit;
    
    var s = audio_play_sound(argument0, 50, loop);
    audio_sound_gain(s, global.volume_sfx, argument1);
    


    Object obj_sound_enable now. Full code is:

    global.volume = !round(global.volume);
    
    if !global.volume
    {
        audio_stop_all();
    }
    

    symbol ! means not.

    if !aaa
    

    is equal

    if (aaa == false)
    

    and

    if aaa
    

    is equal

    if (aaa == true)
    

    In GMS true is equal 1 and false is equal 0 (actually, not only that values, but in this case it doesn't matter). So when I do

    if !global.volume
    

    it equal

    if (global.volume == false)
    

    and it means

    if (global.volume == 0)
    

    i.e. if volume is 0 then stop all sounds.

    First line works similar

    global.volume = !round(global.volume);
    

    Statement

    a = !a
    

    means "if a is true then the new value will be false, and if a is false then the new value will be true".

    a = false;
    b = !a; // now "b" is "true" ("1");
    c = 1;
    d = !c; // now "d" is "0" ("false")
    

    So this is a simple switcher from 0 to 1 and back.

    But volume is real number, not integer, so I round it before "switching". If you need only sound on/sound off button then you don't need round and can use simple global.volume = !global.volume