我在使用MediaPlayer时在XNA中看到了奇怪的行为

时间:2012-03-23 19:51:13

标签: xna media-player

在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 个答案:

答案 0 :(得分:1)

我能够使用您在上面发布的代码在新的游戏项目中重现类似的问题(对我而言,游戏窗口实际上会挂起并变得无法响应)。

我还能够找到遇到类似问题的其他人的论坛帖子(从两年前就像这个一样 - > http://forums.create.msdn.com/forums/t/45296.aspx)。这显然是框架中的一个错误。

我不确定可能会发生什么。我猜测有一些funkiness发生在检查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的内置状态发生的不期望的行为。

答案 1 :(得分:1)

为什么不在实际想要暂停音乐的事件中暂停音乐并在未取消游戏的事件中恢复播放?然后,您不再需要bool变量,并且每次都要检查它。我在PauseScreen类逻辑上做到了。