允许XNA SoundEffectInstance自行播放

时间:2012-03-11 16:18:52

标签: c# xna xna-4.0 soundeffect soundeffectinstance

基本上我有一个声音效果,当两个物品在我的游戏中发生碰撞时播放。有些项目彼此非常接近,因此声音效果可能必须快速连续播放。

使用SoundEffect.Play()可以正常工作。但是为了节省垃圾收集,我想使用一个实例。不幸的是,这意味着在最后一个实例完成播放之前,实例不会播放。这不是我追求的效果。有没有办法覆盖这个功能,还是我必须回到原来的SoundEffect?

2 个答案:

答案 0 :(得分:1)

你有什么理由想“节省垃圾收集吗?”除非你开始遇到实际的性能问题,否则很可能不必担心它。根据个人经验,您可以快速连续播放至少十几种声音(使用SoundEffect.Play())而不会出现任何问题。但是,如果你觉得你的游戏有很多碰撞,你可以做两件事:

首先,考虑创建一个简单的SoundPlayer类来处理您播放的所有声音,并且每当您检测到超过10个同时播放时,请阻止播放下一个。如果发生了很多碰撞,那就不像玩家会注意到丢失的声音。

其次,请点击此处(http://forums.create.msdn.com/forums/t/91165.aspx)了解如何使用DynamicSoundEffectInstance预混音色。这有点复杂,但通过向前看并将所有即将播放的声音混合到单个缓冲区中,您几乎可以保证零延迟,因为只有一个声音(或一个音频流缓冲区)有效播放。

答案 1 :(得分:0)

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);
    }

设置愚蠢的值会导致异常。