14_SoundEffects.as 6.5 KB

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