1// Sound effects example 2// This sample demonstrates: 3// - Playing sound effects and music 4// - Controlling sound and music master volume 5 6#include "Scripts/Utilities/Sample.as" 7 8Array<String> soundNames = { 9 "Fist", 10 "Explosion", 11 "Power-up" 12}; 13 14Array<String> soundResourceNames = { 15 "Sounds/PlayerFistHit.wav", 16 "Sounds/BigExplosion.wav", 17 "Sounds/Powerup.wav" 18}; 19 20SoundSource@ musicSource; 21 22void Start() 23{ 24 // Execute the common startup for samples 25 SampleStart(); 26 27 // Create a scene which will not be actually rendered, but is used to hold SoundSource components while they play sounds 28 scene_ = Scene(); 29 30 // Create music sound source 31 @musicSource = scene_.CreateComponent("SoundSource"); 32 // Set the sound type to music so that master volume control works correctly 33 musicSource.soundType = SOUND_MUSIC; 34 35 // Enable OS cursor 36 input.mouseVisible = true; 37 38 // Create the user interface 39 CreateUI(); 40 41 // Set the mouse mode to use in the sample 42 SampleInitMouseMode(MM_FREE); 43} 44 45void CreateUI() 46{ 47 XMLFile@ uiStyle = cache.GetResource("XMLFile", "UI/DefaultStyle.xml"); 48 // Set style to the UI root so that elements will inherit it 49 ui.root.defaultStyle = uiStyle; 50 51 // Create buttons for playing back sounds 52 for (uint i = 0; i < soundNames.length; ++i) 53 { 54 Button@ button = CreateButton(i * 140 + 20, 20, 120, 40, soundNames[i]); 55 // Store the sound effect resource name as a custom variable into the button 56 button.vars["SoundResource"] = soundResourceNames[i]; 57 SubscribeToEvent(button, "Pressed", "HandlePlaySound"); 58 } 59 60 // Create buttons for playing/stopping music 61 Button@ button = CreateButton(20, 80, 120, 40, "Play Music"); 62 SubscribeToEvent(button, "Released", "HandlePlayMusic"); 63 64 button = CreateButton(160, 80, 120, 40, "Stop Music"); 65 SubscribeToEvent(button, "Released", "HandleStopMusic"); 66 67 // Create sliders for controlling sound and music master volume 68 Slider@ slider = CreateSlider(20, 140, 200, 20, "Sound Volume"); 69 slider.value = audio.masterGain[SOUND_EFFECT]; 70 SubscribeToEvent(slider, "SliderChanged", "HandleSoundVolume"); 71 72 slider = CreateSlider(20, 200, 200, 20, "Music Volume"); 73 slider.value = audio.masterGain[SOUND_MUSIC]; 74 SubscribeToEvent(slider, "SliderChanged", "HandleMusicVolume"); 75} 76 77Button@ CreateButton(int x, int y, int xSize, int ySize, const String&in text) 78{ 79 Font@ font = cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"); 80 81 // Create the button and center the text onto it 82 Button@ button = ui.root.CreateChild("Button"); 83 button.SetStyleAuto(); 84 button.SetPosition(x, y); 85 button.SetSize(xSize, ySize); 86 87 Text@ buttonText = button.CreateChild("Text"); 88 buttonText.SetAlignment(HA_CENTER, VA_CENTER); 89 buttonText.SetFont(font, 12); 90 buttonText.text = text; 91 92 return button; 93} 94 95Slider@ CreateSlider(int x, int y, int xSize, int ySize, const String& text) 96{ 97 Font@ font = cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"); 98 99 // Create text and slider below it 100 Text@ sliderText = ui.root.CreateChild("Text"); 101 sliderText.SetPosition(x, y); 102 sliderText.SetFont(font, 12); 103 sliderText.text = text; 104 105 Slider@ slider = ui.root.CreateChild("Slider"); 106 slider.SetStyleAuto(); 107 slider.SetPosition(x, y + 20); 108 slider.SetSize(xSize, ySize); 109 // Use 0-1 range for controlling sound/music master volume 110 slider.range = 1.0f; 111 112 return slider; 113} 114 115void HandlePlaySound(StringHash eventType, VariantMap& eventData) 116{ 117 Button@ button = GetEventSender(); 118 String soundResourceName = button.vars["SoundResource"].GetString(); 119 120 // Get the sound resource 121 Sound@ sound = cache.GetResource("Sound", soundResourceName); 122 123 if (sound !is null) 124 { 125 // Create a SoundSource component for playing the sound. The SoundSource component plays 126 // non-positional audio, so its 3D position in the scene does not matter. For positional sounds the 127 // SoundSource3D component would be used instead 128 SoundSource@ soundSource = scene_.CreateComponent("SoundSource"); 129 soundSource.autoRemoveMode = REMOVE_COMPONENT; 130 soundSource.Play(sound); 131 // In case we also play music, set the sound volume below maximum so that we don't clip the output 132 soundSource.gain = 0.7f; 133 } 134} 135 136void HandlePlayMusic(StringHash eventType, VariantMap& eventData) 137{ 138 Sound@ music = cache.GetResource("Sound", "Music/Ninja Gods.ogg"); 139 // Set the song to loop 140 music.looped = true; 141 142 musicSource.Play(music); 143} 144 145void HandleStopMusic(StringHash eventType, VariantMap& eventData) 146{ 147 musicSource.Stop(); 148} 149 150void HandleSoundVolume(StringHash eventType, VariantMap& eventData) 151{ 152 float newVolume = eventData["Value"].GetFloat(); 153 audio.masterGain[SOUND_EFFECT] = newVolume; 154} 155 156void HandleMusicVolume(StringHash eventType, VariantMap& eventData) 157{ 158 float newVolume = eventData["Value"].GetFloat(); 159 audio.masterGain[SOUND_MUSIC] = newVolume; 160} 161 162// Create XML patch instructions for screen joystick layout specific to this sample app 163String patchInstructions = 164 "<patch>" + 165 " <add sel=\"/element/element[./attribute[@name='Name' and @value='Button2']]\">" + 166 " <attribute name=\"Is Visible\" value=\"false\" />" + 167 " </add>" + 168 " <add sel=\"/element/element[./attribute[@name='Name' and @value='Hat0']]\">" + 169 " <attribute name=\"Is Visible\" value=\"false\" />" + 170 " </add>" + 171 "</patch>"; 172