我一直在将Node.JS FFI更新为SDL以使用SDL2。 (https://github.com/Freezerburn/node-sdl/tree/sdl2)到目前为止,它一直很顺利,我可以成功渲染1600多种彩色纹理而没有太多问题。但是,我刚开始遇到一个我似乎无法弄清楚的问题,似乎与FFI,GC,Javascript的速度等无关。
问题在于,当我在启用VSYNC的情况下调用SDL_RenderPresent时,偶尔每隔几秒钟,此调用将花费20-30或更多毫秒来完成。看起来这种情况连续发生2-3次。这会在屏幕上移动的任何内容中产生非常短暂但明显的视觉障碍。剩下的时间,此调用将花费正常的时间来显示在正确的时间绘制到屏幕上的任何内容,以便与屏幕同步,并且一切看起来都非常流畅。
如果您克隆上面提到的存储库,则可以看到此操作。使用node-gyp构建它,然后运行test.js. (我可以将测试代码嵌入到StackOverflow中,但我认为在GitHub上拥有完整的示例会更容易)需要SDL2,SDL2_ttf,SDL2_image在/ Library / Frameworks中。 (这仍处于开发阶段,所以没有什么可以自动找到SDL2,或者在存储库中拥有所需的代码,或者从某个地方提取等等。)
编辑:这应该可以在gamedev StackExchange网站下进行。不知道是否可以移动/链接。
答案 0 :(得分:2)
在网上做更多研究,我发现了“问题”是什么。这是我之前从未真正遇到的事情,(某种程度上)所以我认为这是一个明显的问题,我没有正确使用SDL。
事实证明,图形“紧张”是每个游戏都可以/确实面临的问题,并且有一些常见的方法来解决它。基本上,问题是CPU无法完全并行运行OS中的每个进程/线程。有时必须暂停一个进程才能运行其他东西。当在帧更新期间发生这种情况时,它可能导致该帧占用实际被推到屏幕的正常时间的两倍。这就是抖动的来源。最明显的是,在阅读Unity question about a similar jitter之后,这就是问题,评论者指出在OS X上运行诸如活动监视器之类的东西会导致抖动每隔几秒定期发生。大约与Activity Monitor轮询所有正在运行的进程以获取信息之间的时间相同。杀死活动监视器会导致抖动不那么规律。
因此,没有真正的方法可以保证您的代码每隔16毫秒运行一次,并且在代码再次运行之前它将始终是另一个16毫秒。您必须将处理事件,移动,AI等的代码的时间与渲染新帧的时间分开,以获得完美流畅的体验。这通常意味着您将每秒运行所有逻辑的次数少于绘制帧的次数,然后预测实际更新之间每个对象的位置,并在该位置绘制对象。有关这方面的一些更具体的细节,请参阅deWiTTERS game loop article,以及一般游戏循环的精彩概述。
请注意,这种提供流畅游戏体验的预测方法并非没有问题。主要的一点是,如果您在预测位置显示一个对象而没有实际对其进行完全碰撞检测,那么该对象可以很容易地剪切到其他对象几帧。在pong克隆中,我正在编写测试SDL绑定,用预测的对象绘图,如果我在靠墙的时候保持正确,那么桨会在弹出之前反复夹入墙中,因为预计位置会比它更远。允许。这是一个必须以不同方式处理的单独问题。我只是让读者知道这个问题。