【问题标题】:Allow XNA SoundEffectInstance to play over itself允许 XNA SoundEffectInstance 自行播放
【发布时间】:2012-03-28 05:41:58
【问题描述】:

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

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

【问题讨论】:

标签: c# xna xna-4.0 soundeffect soundeffectinstance


【解决方案1】:

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

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

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

【讨论】:

  • 啊,如果没有简单的方法来做到这一点,它可能没问题。在我的游戏中不可能一次有 10 次或更多的碰撞,所以我将让它保持正常的 SoundEffect.Play();感谢您的想法。
【解决方案2】:
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);
    }

因为设置一个愚蠢的值会抛出一个异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 2015-08-25
    • 2016-02-24
    • 2023-03-31
    • 2019-07-07
    • 1970-01-01
    相关资源
    最近更新 更多