我已经看过几个问题,但是他们已经三年多了,并且通常最后说的还没有解决它,所以我想知道是否有任何改变。
我正在开发一款使用每秒发生60次的间隔绘制到画布上的游戏。它在我的iphone和PC上工作得很好,它有一个不错的显卡,但我现在正在尝试使用intel i3显卡的Thinkcentre,我注意到一些巨大的屏幕撕裂: http://s21.postimg.org/h6c42hic7/tear.jpg - 作为一个静止注意力有点困难。
我只是想知道是否有办法减少它,或者轻松启用垂直同步。如果没有,那么我可以在我的Windows 8应用程序端口中做些什么吗?
答案 0 :(得分:2)
您使用的是requestAnimationFrame(RAF)吗? RAF将进行v-sync,但setTimeout / setInterval不会。
http://msdn.microsoft.com/library/windows/apps/hh920765
此外,由于30fps足以让您的用户看到平滑的动作,如何将60fps分成2个交替的部分:
在一帧(无图纸)中“计算/更新”
然后在下一帧中完成所有绘图。
然后,了解Chrome的时间线工具。这个出色的小工具可让您分析代码,以发现代码占用时间最多的地方。然后重构代码的这一部分以获得高性能。
[添加:有关requestAnimationFrame的更多有用详情]
Canvas不直接绘制到显示屏幕。相反,canvas将“渲染”到临时的屏幕外缓冲区。 “渲染”是指执行画布命令以在屏幕外缓冲区上绘制的过程。当下一次屏幕刷新发生时,此屏幕外缓冲区将快速绘制到实际显示屏幕。
在刷新期间在实际显示屏幕上绘制屏幕外缓冲区时,屏幕外渲染过程仅部分完成时会发生撕裂。
setInterval不会尝试使用屏幕刷新来协调渲染。因此,使用setInterval控制动画帧有时会产生撕裂。
requestAnimationFrame(RAF)尝试通过仅在屏幕刷新之间生成帧来修复撕裂(称为垂直同步的过程)。典型的显示器每秒刷新约60次(每16毫秒)。
使用requestAnimationFrame(RAF):
如果当前帧未在下次刷新之前完全呈现,
RAF将延迟当前帧的绘制,直到下一次屏幕刷新。
此延迟可减少撕裂。
所以对你而言,英国皇家空军可能会帮助你解决问题,但它也会带来另一个问题。
您必须决定如何处理物理处理:
将物理保存在单独的setInterval中。
这有点像乘坐2列火车,每条腿只有1条腿 - 非常困难!您必须确保物理的所有方面始终处于有效状态,因为您永远不知道RAF何时会读取物理进行渲染。您可能必须创建物理变量的“缓冲区”,以便它们始终处于有效状态。
将物理场转移到RAF中:
如果你可以在刷新之间的16ms内计算物理和渲染,这个解决方案是理想的。如果不是,您的帧可能会延迟到下一个刷新周期。这导致30fps并不可怕,因为眼睛仍然以30fps感知清晰的运动。最糟糕的情况是延迟有时会发生,有时不会 - 然后你的动画可能会显得生涩。因此,关键是在刷新周期之间尽可能均匀地分布计算。
将物理学转移到网络工作者
Javascript是单线程的。 UI和计算都必须在这个单线程上运行。但是您可以使用在单独的线程上运行物理的Web工作者。这释放了UI线程,专注于渲染和绘制。但是你必须使用前景UI协调背景物理。
祝你好运:)