Разрешить XNA SoundEffectInstance воспроизводить себя - PullRequest
0 голосов
/ 11 марта 2012

По сути, у меня есть звуковой эффект, который воспроизводится, когда в моей игре сталкиваются два предмета.Некоторые элементы расположены довольно близко друг к другу, поэтому звуковой эффект может быть воспроизведен в быстрой последовательности.

Используя SoundEffect.Play () это работает.Однако, чтобы сэкономить на сборке мусора, я хочу использовать экземпляр.К сожалению, это означает, что экземпляр не будет воспроизводиться до тех пор, пока последний не закончит играть.Это не тот эффект, который был после.Есть ли способ перезаписать эту функциональность, или мне придется вернуться к простому старому SoundEffect? ​​

Ответы [ 2 ]

1 голос
/ 11 марта 2012

Есть ли причина, по которой вы хотите "сэкономить на сборе мусора"?Если вы не столкнетесь с реальными проблемами производительности, вам, скорее всего, не о чем беспокоиться.Исходя из личного опыта, вы можете воспроизводить не менее десятка звуков в быстрой последовательности (используя SoundEffect.Play()) без каких-либо проблем.Однако, если вы чувствуете, что в вашей игре много коллизий, вы можете сделать две вещи:

Во-первых, подумайте о создании простого класса SoundPlayer, который обрабатывает все звуки, которые вы играете, и всякий раз, когда вы обнаруживаете болееоколо 10 игр одновременно, не позволяйте воспроизвести следующий.Не похоже, чтобы игрок заметил пропущенные звуки, если происходит много столкновений.

Во-вторых, посмотрите здесь (http://forums.create.msdn.com/forums/t/91165.aspx) о том, как использовать DynamicSoundEffectInstance для предварительного смешивания звуков. Это немного сложнее, но если посмотреть в будущее и смешать все звуки, которые одля воспроизведения в одном буфере вы в значительной степени гарантируете нулевую задержку, поскольку эффективно воспроизводится только один звук (или один буфер аудиопотока).

0 голосов
/ 15 августа 2014
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);
    }

Поскольку установка глупого значения исключит исключение.

...