Я вижу странное поведение в XNA при использовании MediaPlayer - PullRequest
3 голосов
/ 23 марта 2012

В XNA я использую MediaPlayer для воспроизведения своей музыки.Я обнаружил, что при воспроизведении сборки выпуска (запускаемой как исполняемый файл, а не из Visual Studio) окно игры иногда мерцало и казалось, что оно пыталось свернуть, а затем вернуться.Иногда значок игры на панели задач появляется немного в стороне и скользит обратно туда, где он находится.Я использую Windows 7. Это было легко воспроизвести, запустив игру, сделав окно обозревателя активным, оставив его на секунду или две, затем щелкнув по игре.Для подергивания окна игры требуется около 6-10 секунд, но затем это происходит каждые 4-8 секунд после этого.

Я выяснил, что именно вызвало это, и это следующий код, вызываемый через основное обновление игры.

if (!IsActive && MediaPlayer.State != MediaState.Paused)
{
    MediaPlayer.Pause();
}
if (IsActive && MediaPlayer.State == MediaState.Paused)
{
    MediaPlayer.Resume();
}

По сути, я приостанавливаю музыку при игрене активен и не останавливается, когда игра снова активна.По какой-то причине это все портит.Я пытался просто заглушить музыку вместо паузы, но получаю тот же эффект.Я сделал новую игру для PC XNA 4.0, но даже с использованием только вышеприведенного кода (и base.Update) в основной функции обновления это все же происходит, так что это определенно код, вызывающий проблему.Кто-нибудь знает, что здесь происходит, или другой способ приостановить музыку, когда игра неактивна?

Ответы [ 2 ]

1 голос
/ 28 апреля 2013

Почему бы не приостановить воспроизведение музыки в событиях, где вы действительно хотите приостановить воспроизведение музыки, и возобновить воспроизведение в событиях, которые делают игру приостановленной?Затем вы устраняете необходимость в переменной bool и проверяете ее каждый раз.Я сделал это на моей логике класса PauseScreen.

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

Мне удалось воспроизвести аналогичную проблему (для меня окно Игры будет зависать и перестать отвечать на запросы) в новом игровом проекте с использованием кода, который вы разместили выше.

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

Я не совсем уверен, что может происходить.Я предполагаю, что с проверкой MediaPlayer может происходить какая-то забавность, которая может отнимать фокус у окна, а затем возвращаться к игре, которая возвращает фокус, так что в течение нескольких миллисекунд игра проигрывает и получает фокус, так что музыка приостанавливается, возобновляется, приостанавливается.и снова со скоростью 60 раз в секунду.На более слабых машинах, таких как моя, это приводит к тому, что окно перестает отвечать на запросы.Это всего лишь гипотеза, поскольку я не знаю наверняка, но это имеет смысл.

Однако я смог обойти эту проблему, просто вырезав проверку состояния MediaPlayer из уравнения.Если у вас есть собственный логический флаг, который вы добавляете в игру (что-то вроде «isPlaying»), а затем запрашиваете эту логическую переменную вместо проверки состояния MediaPlayer, проблема устраняется, и вы получаете желаемую функциональность.

Код будет выглядеть примерно так:

bool isMusicPlaying = false;
protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);

    Song song = Content.Load<Song>("SampleSong");
    MediaPlayer.Play(song);
    isMusicPlaying = true;
}

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();

    if (!IsActive && isMusicPlaying == true)
    {
        MediaPlayer.Pause();
        isMusicPlaying = false;
    }
    else if (IsActive && isMusicPlaying == false)
    {
        MediaPlayer.Resume();
        isMusicPlaying = true;
    }

    base.Update(gameTime);
}

С помощью приведенного выше кода вы все равно должны получить оригинальную функциональность, которую искали, и избавиться от нежелательного поведения, которое происходило с использованием встроенного состояния MediaPlayer.

...