Tl;dr 您正在对DrawMiniMap 方法的每次调用 创建一个名为dummyTexture 的新Texture2D 实例(1x1 像素)。这是一个坏主意,因为每次都需要将纹理发送到 GPU(然后处理和收集)。添加一个名为dummyTexture 的字段,并在LoadContent 中对其进行完全初始化。
但请阅读帖子的其余部分,了解如何识别这些问题。
您的 Update 方法以 60fps 的速度被调用,但 Draw 方法也不一定如此。由于Game.IsFixedTimeStep 默认设置为true,一旦Monogame 发现Draw 的完成时间比预期的要长,您的Draw 方法就会跳帧。
由于您现在编写游戏逻辑的方式,这是 Monogame 确保所有更新都在固定时间步长内完成的唯一方法。
为了更好地了解正在发生的事情,首先为Draw 方法 fps 创建一组额外的 fps 变量,然后在屏幕上渲染这两个值。您会看到 Update 以 60 fps 的速度绘制,但 Draw 低于该速度。
protected override void Draw(GameTime gameTime)
{
// similar to what you have inside `Update`
drawFpsTimer += gameTime.ElapsedGameTime;
drawFpsCount++;
if (drawFpsTimer >= TimeSpan.FromSeconds(1))
{ drawFpsTimer = TimeSpan.FromSeconds(0); drawFps = drawFpsCount; drawFpsCount = 0; }
...
有了这个,就很容易在Draw 中查明有问题的方法,并将你的 fps 恢复到 60。
此外,通过将IsFixedTimeStep 设置为false,您可以同时调用Update 和Draw,但您的Update 帧速率也会下降——这意味着您应该更改所有更新逻辑使用gameTime.ElapsedGameTime 而不是假定固定步骤:
protected override void Initialize()
{
// use variable time step
this.IsFixedTimeStep = false;
this.TargetElapsedTime = TimeSpan.FromSeconds(1 / 60.0);
this.graphics.SynchronizeWithVerticalRetrace = true;
...
在我的所有项目中,我更喜欢可变时间步长,尤其是当您发现 XNA sometimes takes up 100% CPU time on one core when the default value of Game.IsFixedTimeStep is used,但准备好进行一些重构时。
至于 为什么 帧被跳过,似乎是 DrawMiniMap 方法有问题。对此发表评论会在我的机器上提供 60 fps 更新 + 60 fps 绘制速率。
经过进一步检查,发现您在每次调用此方法时创建了一个名为 dummyTexture 的新 Texture2D 实例(1x1 像素)。这是一个坏主意。添加一个名为dummyTexture 的字段并在LoadContent 中完全初始化它。您还可以通过使tileColour 成为Tile 类的成员来稍微加快此方法的速度,以避免在每次迭代中进行大量if 测试,但可能有很多这样的优化,除非您是部署到移动设备。