diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room2.tscn b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room2.tscn index a9c17b4..f8bc58c 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room2.tscn +++ b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room2.tscn @@ -153,7 +153,7 @@ [node name="EnemyMark13" type="Node2D" parent="."] position = Vector2(211, 79) script = ExtResource("3_v71xh") -Weapon1Id = "0005(ResidueAmmo:10,CurrAmmon:0)" +Weapon1Id = "0005(ResidueAmmo:0,CurrAmmon:10)" Type = 4 ItemExpression = "0001" Layer = 1 diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room3.tscn b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room3.tscn index 9148a89..5499714 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room3.tscn +++ b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room3.tscn @@ -118,7 +118,7 @@ [node name="EnemyMark9" type="Node2D" parent="."] position = Vector2(56, 67) script = ExtResource("3_u8a04") -Weapon1Id = "0005(ResidueAmmo:10,CurrAmmon:0)" +Weapon1Id = "0005(ResidueAmmo:0,CurrAmmon:10)" Type = 4 ItemExpression = "0001" Layer = 1 diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room4.tscn b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room4.tscn index 78d6f90..fdf3fff 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room4.tscn +++ b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room4.tscn @@ -149,7 +149,7 @@ [node name="EnemyMark13" type="Node2D" parent="."] script = ExtResource("3_tkueb") -Weapon1Id = "0005(ResidueAmmo:10,CurrAmmon:0)" +Weapon1Id = "0005(ResidueAmmo:0,CurrAmmon:10)" Type = 4 ItemExpression = "0001" Layer = 1 @@ -161,7 +161,7 @@ [node name="EnemyMark14" type="Node2D" parent="."] position = Vector2(346, -8) script = ExtResource("3_tkueb") -Weapon1Id = "0005(ResidueAmmo:10,CurrAmmon:0)" +Weapon1Id = "0005(ResidueAmmo:0,CurrAmmon:10)" Type = 4 ItemExpression = "0001" Layer = 1 @@ -173,7 +173,7 @@ [node name="EnemyMark15" type="Node2D" parent="."] position = Vector2(359, 312) script = ExtResource("3_tkueb") -Weapon1Id = "0005(ResidueAmmo:10,CurrAmmon:0)" +Weapon1Id = "0005(ResidueAmmo:0,CurrAmmon:10)" Type = 4 ItemExpression = "0001" Layer = 1 @@ -185,7 +185,7 @@ [node name="EnemyMark16" type="Node2D" parent="."] position = Vector2(-8, 311) script = ExtResource("3_tkueb") -Weapon1Id = "0005(ResidueAmmo:10,CurrAmmon:0)" +Weapon1Id = "0005(ResidueAmmo:0,CurrAmmon:10)" Type = 4 ItemExpression = "0001" Layer = 1 diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room8.tscn b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room8.tscn index f888e92..fecb878 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room8.tscn +++ b/DungeonShooting_Godot/resource/map/tileMaps/testGroup/battle/Room8.tscn @@ -179,7 +179,7 @@ [node name="EnemyMark10" type="Node2D" parent="."] position = Vector2(66, 125) script = ExtResource("3_y6it6") -Weapon1Id = "0005(ResidueAmmo:10,CurrAmmon:0)" +Weapon1Id = "0005(ResidueAmmo:0,CurrAmmon:10)" Type = 4 ItemExpression = "0001" Layer = 1 diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs index 73ecc5c..a7580e3 100644 --- a/DungeonShooting_Godot/src/game/GameApplication.cs +++ b/DungeonShooting_Godot/src/game/GameApplication.cs @@ -138,6 +138,7 @@ { var newDelta = (float)delta; InputManager.Update(newDelta); + SoundManager.Update(newDelta); //协程更新 if (_coroutineList != null) diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs index 7c6c912..4cae2a7 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs @@ -1090,13 +1090,14 @@ if (Attribute.BeginReloadSound != null) { var position = GameApplication.Instance.ViewToGlobalPosition(GlobalPosition); + var volume = SoundManager.CalcRoleVolume(Attribute.BeginReloadSound.Volume, Master); if (Attribute.BeginReloadSoundDelayTime <= 0) { - SoundManager.PlaySoundEffectPosition(Attribute.BeginReloadSound.Path, position, Attribute.BeginReloadSound.Volume); + SoundManager.PlaySoundEffectPosition(Attribute.BeginReloadSound.Path, position, volume); } else { - SoundManager.PlaySoundEffectPositionDelay(Attribute.BeginReloadSound.Path, position, Attribute.BeginReloadSoundDelayTime, Attribute.BeginReloadSound.Volume); + SoundManager.PlaySoundEffectPositionDelay(Attribute.BeginReloadSound.Path, position, Attribute.BeginReloadSoundDelayTime, volume); } } } @@ -1107,13 +1108,14 @@ if (Attribute.ReloadSound != null) { var position = GameApplication.Instance.ViewToGlobalPosition(GlobalPosition); + var volume = SoundManager.CalcRoleVolume(Attribute.ReloadSound.Volume, Master); if (Attribute.ReloadSoundDelayTime <= 0) { - SoundManager.PlaySoundEffectPosition(Attribute.ReloadSound.Path, position, Attribute.ReloadSound.Volume); + SoundManager.PlaySoundEffectPosition(Attribute.ReloadSound.Path, position, volume); } else { - SoundManager.PlaySoundEffectPositionDelay(Attribute.ReloadSound.Path, position, Attribute.ReloadSoundDelayTime, Attribute.ReloadSound.Volume); + SoundManager.PlaySoundEffectPositionDelay(Attribute.ReloadSound.Path, position, Attribute.ReloadSoundDelayTime, volume); } } } @@ -1123,8 +1125,9 @@ { if (Attribute.ReloadFinishSound != null) { + var volume = SoundManager.CalcRoleVolume(Attribute.ReloadFinishSound.Volume, Master); var position = GameApplication.Instance.ViewToGlobalPosition(GlobalPosition); - SoundManager.PlaySoundEffectPosition(Attribute.ReloadFinishSound.Path, position, Attribute.ReloadFinishSound.Volume); + SoundManager.PlaySoundEffectPosition(Attribute.ReloadFinishSound.Path, position, volume); } } @@ -1133,8 +1136,9 @@ { if (Attribute.ShootSound != null) { + var volume = SoundManager.CalcRoleVolume(Attribute.ShootSound.Volume, Master); var position = GameApplication.Instance.ViewToGlobalPosition(GlobalPosition); - SoundManager.PlaySoundEffectPosition(Attribute.ShootSound.Path, position, Attribute.ShootSound.Volume); + SoundManager.PlaySoundEffectPosition(Attribute.ShootSound.Path, position, volume); } } @@ -1144,13 +1148,14 @@ if (Attribute.BeLoadedSound != null) { var position = GameApplication.Instance.ViewToGlobalPosition(GlobalPosition); + var volume = SoundManager.CalcRoleVolume(Attribute.BeLoadedSound.Volume, Master); if (Attribute.BeLoadedSoundDelayTime <= 0) { - SoundManager.PlaySoundEffectPosition(Attribute.BeLoadedSound.Path, position, Attribute.BeLoadedSound.Volume); + SoundManager.PlaySoundEffectPosition(Attribute.BeLoadedSound.Path, position, volume); } else { - SoundManager.PlaySoundEffectPositionDelay(Attribute.BeLoadedSound.Path, position, Attribute.BeLoadedSoundDelayTime, Attribute.BeLoadedSound.Volume); + SoundManager.PlaySoundEffectPositionDelay(Attribute.BeLoadedSound.Path, position, Attribute.BeLoadedSoundDelayTime, volume); } } } diff --git a/DungeonShooting_Godot/src/game/manager/SoundManager.cs b/DungeonShooting_Godot/src/game/manager/SoundManager.cs index c6e2cd7..bcf7ea4 100644 --- a/DungeonShooting_Godot/src/game/manager/SoundManager.cs +++ b/DungeonShooting_Godot/src/game/manager/SoundManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using Godot; @@ -16,27 +17,51 @@ /// public partial class SoundManager { - private static Stack _streamPlayer2DStack = new Stack(); - private static Stack _streamPlayerStack = new Stack(); + /// + /// 全局音效音量, 范围 0 - 1 + /// + public static float SoundVolume { get; set; } = 0.4f; + + private static Stack _streamPlayer2DStack = new Stack(); + private static Stack _streamPlayerStack = new Stack(); + private static HashSet _playingSoundResourceList = new HashSet(); /// /// 2D音频播放节点 /// - private partial class AudioPlayer2D : AudioStreamPlayer2D + public partial class GameAudioPlayer2D : AudioStreamPlayer2D { - private float _delayTimer = -1; - public override void _Ready() { Finished += OnPlayFinish; } - /// - /// 延时播放 - /// - public void DelayPlay(float time) + public void PlaySoundByResource(string path, float delayTime) { - _delayTimer = time; + if (delayTime <= 0) + { + PlaySoundByResource(path); + } + else + { + GameApplication.Instance.StartCoroutine(DelayPlay(path, delayTime)); + } + } + + public void PlaySoundByResource(string path) + { + if (_playingSoundResourceList.Contains(path)) + { + GD.Print("重复播放: " + path); + } + else + { + _playingSoundResourceList.Add(path); + var sound = ResourceManager.Load(path); + Stream = sound; + Bus = Enum.GetName(typeof(BUS), 1); + Play(); + } } /// @@ -47,31 +72,25 @@ Stop(); OnPlayFinish(); } - - public override void _Process(double delta) - { - if (_delayTimer > 0) - { - _delayTimer -= (float)delta; - if (_delayTimer <= 0) - { - Play(); - } - } - } - + private void OnPlayFinish() { - _delayTimer = -1; RecycleAudioPlayer2D(this); } + + private IEnumerator DelayPlay(string path, float delayTime) + { + yield return new WaitForSeconds(delayTime); + PlaySoundByResource(path); + } } /// /// 音频播放节点 /// - private partial class AudioPlayer : AudioStreamPlayer + public partial class GameAudioPlayer : AudioStreamPlayer { + public string SoundResourceName { get; set; } public override void _Ready() { Finished += OnPlayFinish; @@ -95,12 +114,17 @@ } } + public static void Update(float delta) + { + _playingSoundResourceList.Clear(); + } + /// /// 播放声音 用于bgm /// /// bgm路径 /// 音量 - public static AudioStreamPlayer PlayMusic(string soundName, float volume = 0.5f) + public static GameAudioPlayer PlayMusic(string soundName, float volume = 0.5f) { var sound = ResourceManager.Load(soundName); var soundNode = GetAudioPlayerInstance(); @@ -117,7 +141,7 @@ /// /// 音效文件路径 /// 音量 (0 - 1) - public static AudioStreamPlayer PlaySoundEffect(string soundName, float volume = 1f) + public static GameAudioPlayer PlaySoundEffect(string soundName, float volume = 1f) { var sound = ResourceManager.Load(soundName); var soundNode = GetAudioPlayerInstance(); @@ -136,25 +160,9 @@ /// 发声节点所在全局坐标 /// 音量 (0 - 1) /// 挂载节点, 为null则挂载到房间根节点下 - public static AudioStreamPlayer2D PlaySoundEffectPosition(string soundName, Vector2 pos, float volume = 1f, Node2D target = null) + public static GameAudioPlayer2D PlaySoundEffectPosition(string soundName, Vector2 pos, float volume = 1f, Node2D target = null) { - var sound = ResourceManager.Load(soundName); - var soundNode = GetAudioPlayer2DInstance(); - if (target != null) - { - target.AddChild(soundNode); - } - else - { - GameApplication.Instance.GlobalNodeRoot.AddChild(soundNode); - } - - soundNode.GlobalPosition = pos; - soundNode.Stream = sound; - soundNode.Bus = Enum.GetName(typeof(BUS), 1); - soundNode.VolumeDb = Mathf.LinearToDb(Mathf.Clamp(volume, 0, 1)); - soundNode.Play(); - return soundNode; + return PlaySoundEffectPositionDelay(soundName, pos, 0, volume, target); } /// @@ -165,9 +173,8 @@ /// 延时时间 /// 音量 (0 - 1) /// 挂载节点, 为null则挂载到房间根节点下 - public static AudioStreamPlayer2D PlaySoundEffectPositionDelay(string soundName, Vector2 pos, float delayTime, float volume = 1f, Node2D target = null) + public static GameAudioPlayer2D PlaySoundEffectPositionDelay(string soundName, Vector2 pos, float delayTime, float volume = 1f, Node2D target = null) { - var sound = ResourceManager.Load(soundName); var soundNode = GetAudioPlayer2DInstance(); if (target != null) { @@ -179,24 +186,22 @@ } soundNode.GlobalPosition = pos; - soundNode.Stream = sound; - soundNode.Bus = Enum.GetName(typeof(BUS), 1); - soundNode.VolumeDb = Mathf.LinearToDb(Mathf.Clamp(volume, 0, 1)); - soundNode.DelayPlay(delayTime); + soundNode.VolumeDb = Mathf.LinearToDb(Mathf.Clamp(volume * SoundVolume, 0, 1)); + soundNode.PlaySoundByResource(soundName, delayTime); return soundNode; } /// /// 获取2D音频播放节点 /// - private static AudioPlayer2D GetAudioPlayer2DInstance() + private static GameAudioPlayer2D GetAudioPlayer2DInstance() { if (_streamPlayer2DStack.Count > 0) { return _streamPlayer2DStack.Pop(); } - var inst = new AudioPlayer2D(); + var inst = new GameAudioPlayer2D(); inst.AreaMask = 0; return inst; } @@ -204,20 +209,20 @@ /// /// 获取音频播放节点 /// - private static AudioPlayer GetAudioPlayerInstance() + private static GameAudioPlayer GetAudioPlayerInstance() { if (_streamPlayerStack.Count > 0) { return _streamPlayerStack.Pop(); } - return new AudioPlayer(); + return new GameAudioPlayer(); } /// /// 回收2D音频播放节点 /// - private static void RecycleAudioPlayer2D(AudioPlayer2D inst) + private static void RecycleAudioPlayer2D(GameAudioPlayer2D inst) { var parent = inst.GetParent(); if (parent != null) @@ -232,8 +237,21 @@ /// /// 回收音频播放节点 /// - private static void RecycleAudioPlayer(AudioPlayer inst) + private static void RecycleAudioPlayer(GameAudioPlayer inst) { _streamPlayerStack.Push(inst); } + + /// + /// 计算指定角色播放音效使用的音量 + /// + public static float CalcRoleVolume(float volume, Role role) + { + if (role is not Player) + { + return volume * 0.4f; + } + + return volume; + } } \ No newline at end of file