允许XNA SoundEffectInstance自己播放
本文关键字:播放 自己 SoundEffectInstance XNA 允许 | 更新日期: 2023-09-27 18:27:37
本质上,当我的游戏中两个项目发生碰撞时,我会播放一个音效。有些项目彼此非常接近,因此音效可能必须快速连续播放。
使用SoundEffect.Play()可以。然而,为了节省垃圾回收,我想使用一个实例。不幸的是,这意味着在最后一个实例完成播放之前,实例不会播放。这不是我想要的效果。有没有办法重写这个功能,或者我必须回到普通的旧SoundEffect?
你有什么理由想要"节省垃圾回收"吗?除非你开始遇到实际的性能问题,否则很可能不需要担心。根据个人经验,你可以快速连续播放至少十几个声音(使用SoundEffect.Play()
)而不会有任何问题。然而,如果你觉得你的游戏有很多冲突,你可以做两件事:
首先,考虑创建一个简单的SoundPlayer
类来处理您播放的所有声音,每当您检测到同时播放的声音超过10个时,请阻止播放下一个。如果发生了很多碰撞,玩家不会注意到缺失的声音。
第二,看看这里(http://forums.create.msdn.com/forums/t/91165.aspx)关于如何使用CCD_ 3来预混合声音。这有点复杂,但通过向前看并将所有即将播放的声音混合到一个缓冲区中,你几乎可以保证零滞后,因为只有一个声音(或一个音频流缓冲区)有效播放。
List<SoundEffectInstance> explosionSoundInstanceList;
explosionSound = Content.Load<SoundEffect>("sound/explosion");
explosionSoundInstanceList = new List<SoundEffectInstance>(MAX_EXPLOSIONS);
for (int i = 0; i < MAX_EXPLOSIONS; i++)
{
explosionSoundInstanceList.Add(explosionSound.CreateInstance());
}
private void PlayExplosionSound(float volume, float pitch, float pan)
{
ClampSoundValues(ref volume, ref pitch, ref pan);
for (int i = 0; i < explosionSoundInstanceList.Count; i++)
{
if (explosionSoundInstanceList[i].State == SoundState.Stopped)
{
explosionSoundInstanceList[i].Volume = volume / (i+1);
explosionSoundInstanceList[i].Pitch = pitch;
explosionSoundInstanceList[i].Pan = pan;
explosionSoundInstanceList[i].Play();
return;
}
}
return;
}
工作正常。实例化后360上的零垃圾。在你达到极限后,它会优雅地失败。
这就是我使用的。
我如此钳制的值
private static void ClampSoundValues(ref float volume, ref float pitch, ref float pan)
{
volume = MathHelper.Clamp(volume, -1f, 1f);
pitch = MathHelper.Clamp(pitch, -1f, 1f);
pan = MathHelper.Clamp(pan, -1f, 1f);
}
因为设置一个愚蠢的值会导致一个异常。