2016-03-08 139 views
1

我已经开始使用xna/monogame开发新游戏。我之前设计了一些2D游戏,但决定让这个等距对我来说是新的。我一直在使用reimers等轴瓦引擎教程,其最简单的大部分绘图代码都是这个副本。绘制期间的滚动延迟

当在地图上滚动时,屏幕上出现一个口吃,我只能描述为滞后。我已经把一个FPS计数器,并保持在一个坚实的60,所以我认为这是某种图形问题。

我已经尝试过注释绘图代码的各个部分来缩小问题的范围,但似乎无法取得任何进展,但是几周前这种情况并没有发生,所以我相信它已添加了一些东西,可能是问题引起它的瓦片集?

任何建议表示赞赏。我没有在这里写任何代码,因为它变成了一个相当大的项目,我不知道哪个领域要专注,但如果有人愿意进行调查,我已经上传了整个项目here

+0

Micky,什么部分将是有用的?昨天晚上我进行了一些测试,当游戏第一次启动时,它似乎变得更糟,并且在滚动一下之后几乎停止,就好像它在第一次加载纹理时看到它们并且在该点之后正常工作。 – user3208483

+0

在.NET游戏中出现口吃可能是由于踢入GC引起的。请查看Shawn Hargreaves和Riemer在其各自的XNA博客中的提示。至于启动滞后,您是否做过任何形式的按需加载资产? – MickyD

+0

谢谢,我会仔细研究一下。没有我输入的按需加载,想知道XNA是否自己做,但我确信事实并非如此? – user3208483

回答

3

文艺青年最爱的你正在创建一个新的Texture2D实例(1x1像素)的每次调用DrawMiniMap方法称为dummyTexture。这是一个坏主意,因为纹理需要每次发送到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

此外,通过设置IsFixedTimeStepfalse,你可以同时获得UpdateDraw被称为在继承,但是你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的提取率。

经进一步检查,原来你正在创建一个新的Texture2D实例(1x1像素)呼吁dummyTexture每次调用此方法。这是一个坏主意。添加一个名为dummyTexture的字段,并在LoadContent内完全初始化它。通过使tileColour成为Tile类的成员,以避免在每次迭代中进行大量的if测试,但也可能会稍微加快此方法的速度,但可能有许多此类优化,可能不需要,除非您要部署到移动设备。

+0

感谢所有的信息,非常有帮助,我会看看这个。我会注意到小地图代码是一个新的加法,并且在那之前我遇到了问题。完全忘记移动虚拟纹理,谢谢提醒! :p – user3208483

+1

真的很好阅读,并不是每个人都会从标记为可疑网站的文件下载文件,除了相关文件之外调试/读取所有文件以撰写详细的答案。 – Prix

+0

@ user3218507:好的,这是我在我的机器上看到的。游戏*对于这样一个看似简单的游戏已经很奇怪了,例如如果我禁用vsync并注释掉除DrawCursor部分(这是您绘制fps的地方)以外的所有内容,帧速率将降至〜400fps,如预期的那样。但是,随着和所有东西的绘制,帧频接近80fps(vsync禁用),这意味着你没有太多空间。所以我建议你使用一个探查器,并尝试找到所有其他瓶颈。 – Groo