Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / manager / SoundManager.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 音频总线 区分不同的声音 添加声音效果 目前只有背景音乐 和音效 两个bus
  7. /// </summary>
  8. public enum BUS
  9. {
  10. BGM = 0,
  11. SFX = 1
  12. }
  13.  
  14. /// <summary>
  15. /// 声音管理 背景音乐管理 音效
  16. /// </summary>
  17. public class SoundManager
  18. {
  19. private static Stack<AudioPlayer2D> _streamPlayer2DStack = new Stack<AudioPlayer2D>();
  20. private static Stack<AudioPlayer> _streamPlayerStack = new Stack<AudioPlayer>();
  21.  
  22. /// <summary>
  23. /// 2D音频播放节点
  24. /// </summary>
  25. private class AudioPlayer2D : AudioStreamPlayer2D
  26. {
  27. public override void _Ready()
  28. {
  29. Connect("finished", this, nameof(OnPlayFinish));
  30. }
  31.  
  32. public void OnPlayFinish()
  33. {
  34. RecycleAudioPlayer2D(this);
  35. }
  36. }
  37.  
  38. /// <summary>
  39. /// 音频播放节点
  40. /// </summary>
  41. private class AudioPlayer : AudioStreamPlayer
  42. {
  43. public override void _Ready()
  44. {
  45. Connect("finished", this, nameof(OnPlayFinish));
  46. }
  47.  
  48. public void OnPlayFinish()
  49. {
  50. RecycleAudioPlayer(this);
  51. }
  52. }
  53.  
  54. /// <summary>
  55. /// 播放声音 用于bgm
  56. /// </summary>
  57. /// <param name="soundName">bgm路径</param>
  58. /// <param name="volume">音量</param>
  59. public static AudioStreamPlayer PlayMusic(string soundName, float volume = 0.5f)
  60. {
  61. var sound = ResourceManager.Load<AudioStream>(soundName);
  62. var soundNode = GetAudioPlayerInstance();
  63. GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
  64. soundNode.Stream = sound;
  65. soundNode.Bus = Enum.GetName(typeof(BUS), 0);
  66. soundNode.VolumeDb = volume;
  67. soundNode.Play();
  68. return soundNode;
  69. }
  70.  
  71. /// <summary>
  72. /// 添加并播放音效 用于音效
  73. /// </summary>
  74. /// <param name="soundName">音效文件路径</param>
  75. /// <param name="volume">音量</param>
  76. public static AudioStreamPlayer PlaySoundEffect(string soundName, float volume = 0.5f)
  77. {
  78. var sound = ResourceManager.Load<AudioStream>(soundName);
  79. var soundNode = GetAudioPlayerInstance();
  80. GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
  81. soundNode.Stream = sound;
  82. soundNode.Bus = Enum.GetName(typeof(BUS), 1);
  83. soundNode.VolumeDb = volume;
  84. soundNode.Play();
  85. return soundNode;
  86. }
  87.  
  88. /// <summary>
  89. /// 在指定的节点下播放音效 用于音效
  90. /// </summary>
  91. /// <param name="soundName">音效文件路径</param>
  92. /// <param name="pos">发声节点所在全局坐标</param>
  93. /// <param name="volume">音量</param>
  94. /// <param name="target">挂载节点, 为null则挂载到房间根节点下</param>
  95. public static AudioStreamPlayer2D PlaySoundEffectPosition(string soundName, Vector2 pos, float volume = 0.5f, Node2D target = null)
  96. {
  97. var sound = ResourceManager.Load<AudioStream>(soundName);
  98. var soundNode = GetAudioPlayer2DInstance();
  99. if (target != null)
  100. {
  101. target.AddChild(soundNode);
  102. }
  103. else
  104. {
  105. GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode);
  106. }
  107. soundNode.GlobalPosition = pos;
  108. soundNode.Stream = sound;
  109. soundNode.Bus = Enum.GetName(typeof(BUS), 1);
  110. soundNode.VolumeDb = volume;
  111. soundNode.Play();
  112. return soundNode;
  113. }
  114.  
  115. /// <summary>
  116. /// 获取2D音频播放节点
  117. /// </summary>
  118. private static AudioPlayer2D GetAudioPlayer2DInstance()
  119. {
  120. if (_streamPlayer2DStack.Count > 0)
  121. {
  122. return _streamPlayer2DStack.Pop();
  123. }
  124.  
  125. var inst = new AudioPlayer2D();
  126. inst.AreaMask = 0;
  127. return inst;
  128. }
  129.  
  130. /// <summary>
  131. /// 获取音频播放节点
  132. /// </summary>
  133. private static AudioPlayer GetAudioPlayerInstance()
  134. {
  135. if (_streamPlayerStack.Count > 0)
  136. {
  137. return _streamPlayerStack.Pop();
  138. }
  139.  
  140. return new AudioPlayer();
  141. }
  142.  
  143. /// <summary>
  144. /// 回收2D音频播放节点
  145. /// </summary>
  146. private static void RecycleAudioPlayer2D(AudioPlayer2D inst)
  147. {
  148. var parent = inst.GetParent();
  149. if (parent != null)
  150. {
  151. parent.RemoveChild(inst);
  152. }
  153.  
  154. inst.Stream = null;
  155. _streamPlayer2DStack.Push(inst);
  156. }
  157.  
  158. /// <summary>
  159. /// 回收音频播放节点
  160. /// </summary>
  161. private static void RecycleAudioPlayer(AudioPlayer inst)
  162. {
  163. var parent = inst.GetParent();
  164. if (parent != null)
  165. {
  166. parent.RemoveChild(inst);
  167. }
  168.  
  169. inst.Stream = null;
  170. _streamPlayerStack.Push(inst);
  171. }
  172. }