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.
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