为什么游戏有时会在monogame / xna中跳过帧?

问题描述

这是一个从MonoGame跨平台桌面模板创建的简单项目。我创建了一个球Texture2D并试图使其移动。因此我向Update函数添加了一些代码

position.X += 3;

然后在Draw函数

_spriteBatch.Begin();
_spriteBatch.Draw(ballTexture,position,Color.White);
_spriteBatch.End();

我有时看到球在闪烁。 为什么会这样,我该怎么做才能使其不跳过帧?

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace SimpleTest
{
    public class Game1 : Game
    {
        private GraphicsDeviceManager _graphics;
        private SpriteBatch _spriteBatch;

        private Texture2D dirtTexture;
        private Vector2 position;
        private int direction = 1;

        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }

        protected override void Initialize()
        {
            // Todo: Add your initialization logic here

            base.Initialize();
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);

            // Todo: use this.Content to load your game content here
            dirtTexture = Content.Load<Texture2D>("dirt");
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            // Todo: Add your update logic here

            base.Update(gameTime);

            if (position.X > 600)
                direction = -1;
            else if (position.X < 100)
                direction = 1;

            position.X = position.X + direction * 3;
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // Todo: Add your drawing code here
            _spriteBatch.Begin();
            _spriteBatch.Draw(dirtTexture,Color.White);
            _spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

解决方法

我认为base.Update(gameTime);仅应放在Update()方法的最后,就像base.Draw(gameTime);一样。这样一来,它就不会跳过任何行。

,

我想您的PC可能运行缓慢,这是问题所在,而不是您的代码。要对其进行测试,可以按以下方式替换Draw方法:

    protected override void Draw(GameTime gameTime)
    {
        Color color=gameTime.IsRunningSlowly?Color.Red:Color.CornflowerBlue;
        GraphicsDevice.Clear(color);

        // TODO: Add your drawing code here
        _spriteBatch.Begin();
        _spriteBatch.Draw(dirtTexture,position,Color.White);
        _spriteBatch.End();

        base.Draw(gameTime);
    }

一切都一样,只是现在只有当游戏运行缓慢时(这取决于您的PC),我们才将屏幕着色为红色而不是通常的蓝色。我们可以通过gameTime变量知道这一点,如方法的前两行所示。测试一下,看看是否发生跳帧时游戏背景变红。

我确实在PC上测试了您的确切代码,并且工作正常。不用说,我确实使用了其他一些png来代替您使用的“ dirt” Texture2D,但我认为这没有必要。

,

也许是由于GC。您可以使用几乎没有垃圾的构建进行验证。 您可以从herenuget package安装更新的SDK。