使用 CreateJS 按下鼠标并移动 chrome canvas 至 30FPS
Mouse down and moving drops chrome canvas to 30FPS using CreateJS
我一直在为几个 canvas 游戏项目使用 createjs Easeljs 库。总而言之,我印象深刻,但我最近在 chrome 中遇到了一个阻碍我前进的问题。
当按下鼠标左键并移动鼠标时,FPS 在 chrome 上降至 30(如开发人员工具所报告)。这与游戏通常运行的 60FPS 相比是非常明显的。
为了理解这一点,我删除了一个裸露的 canvas 和自动收报机,但问题仍然存在。所以我迷路了。我可以使用以下代码重现该问题:
<html>
<head>
<script src="./javascript/easeljs-0.8.1.combined.js"></script>
<script>
function init() {
canvas = document.getElementById("gameCanvas");
createjs.Ticker.setFPS(60);
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNC;
stage = new createjs.Stage(canvas);
createjs.Ticker.on("tick", tick);
};
function tick(evt)
{
stage.update();
}
</script>
</head>
<body onLoad="init();" bgcolor="#ffffff">
<canvas id="gameCanvas" width="1136px" height="640px" style="border: thin black solid; margin: 0 auto;"></canvas>
</body>
</html>
我知道这个问题:Html Canvas lag when Left Mouse is down and moving on Chrome但我看不出它在这种情况下有什么帮助。
有没有人有任何想法或资源来帮助解决这个问题?
编辑:
抱歉,我找到了一种解决方法,将代码设置为
createjs.Ticker.timingMode = createjs.Ticker.RAF;
这解决了这些问题和我遇到的间歇性丢帧问题(但没有提到)
无论如何,任何人都可以解释为什么会发生这种情况,以及如果会导致这种情况,我到底为什么要使用同步代码?
RAF 提供了一个不确定的帧率(即,你不能保证任何特定的帧率),这意味着浏览器可以随意限制或增加 fps 以响应任何数量的事情。似乎 Chrome 可能会在鼠标按下时触发额外的 RAF 事件,以便更频繁地重绘并提供更流畅的鼠标交互。
RAF_SYNC
通过尝试将指定帧率与任意帧率对齐来工作。它有一些容差允许它在帧率不一致时工作,但当指定的帧率明显低于现实世界的 RAF 帧率(例如目标 20 或 30 fps)时,它工作得更好。
来自文档:
Variance is usually lowest for framerates that are a
divisor of the RAF frequency. This is usually 60, so framerates of 10,
12, 15, 20, and 30 work well.
在这种情况下,因为您的目标 fps 相当高(基本上可能达到最大 RAF),所以它没有太多回旋余地。当 Chrome 超过 60fps 时,RAF_SYNC 开始无法将帧与它试图达到的帧率对齐。前一帧和当前帧之间没有经过足够的时间,因此它会等待一个额外的帧。结果是帧速率下降到略高于指定速率的一半。在 20 或 30 fps 下,您可能根本不会注意到这一点,因为它可以很好地对齐。
例如,假设 Chrome 跳到 80fps,而您在 RAF_SYNC 模式下的目标是 60fps:
- Chrome 触发英国皇家空军事件。
- Ticker 查看自上次报价以来经过的时间,发现它只有 12 毫秒,认为它还不够接近其 16.67 毫秒的目标,并等待下一个 RAF 事件
- Chrome 触发另一个 RAF 事件。
- Ticker 查看并看到自上次滴答以来已经过去了超过 16.67 毫秒,并立即触发滴答,但此时已经过去了 25 毫秒。
- 重复。您现在 运行 为 ~40fps 而不是 60fps,即使实际帧速率为 ~80fps。
我希望这是有道理的。
我一直在为几个 canvas 游戏项目使用 createjs Easeljs 库。总而言之,我印象深刻,但我最近在 chrome 中遇到了一个阻碍我前进的问题。
当按下鼠标左键并移动鼠标时,FPS 在 chrome 上降至 30(如开发人员工具所报告)。这与游戏通常运行的 60FPS 相比是非常明显的。
为了理解这一点,我删除了一个裸露的 canvas 和自动收报机,但问题仍然存在。所以我迷路了。我可以使用以下代码重现该问题:
<html>
<head>
<script src="./javascript/easeljs-0.8.1.combined.js"></script>
<script>
function init() {
canvas = document.getElementById("gameCanvas");
createjs.Ticker.setFPS(60);
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNC;
stage = new createjs.Stage(canvas);
createjs.Ticker.on("tick", tick);
};
function tick(evt)
{
stage.update();
}
</script>
</head>
<body onLoad="init();" bgcolor="#ffffff">
<canvas id="gameCanvas" width="1136px" height="640px" style="border: thin black solid; margin: 0 auto;"></canvas>
</body>
</html>
我知道这个问题:Html Canvas lag when Left Mouse is down and moving on Chrome但我看不出它在这种情况下有什么帮助。
有没有人有任何想法或资源来帮助解决这个问题?
编辑:
抱歉,我找到了一种解决方法,将代码设置为
createjs.Ticker.timingMode = createjs.Ticker.RAF;
这解决了这些问题和我遇到的间歇性丢帧问题(但没有提到)
无论如何,任何人都可以解释为什么会发生这种情况,以及如果会导致这种情况,我到底为什么要使用同步代码?
RAF 提供了一个不确定的帧率(即,你不能保证任何特定的帧率),这意味着浏览器可以随意限制或增加 fps 以响应任何数量的事情。似乎 Chrome 可能会在鼠标按下时触发额外的 RAF 事件,以便更频繁地重绘并提供更流畅的鼠标交互。
RAF_SYNC
通过尝试将指定帧率与任意帧率对齐来工作。它有一些容差允许它在帧率不一致时工作,但当指定的帧率明显低于现实世界的 RAF 帧率(例如目标 20 或 30 fps)时,它工作得更好。
来自文档:
Variance is usually lowest for framerates that are a divisor of the RAF frequency. This is usually 60, so framerates of 10, 12, 15, 20, and 30 work well.
在这种情况下,因为您的目标 fps 相当高(基本上可能达到最大 RAF),所以它没有太多回旋余地。当 Chrome 超过 60fps 时,RAF_SYNC 开始无法将帧与它试图达到的帧率对齐。前一帧和当前帧之间没有经过足够的时间,因此它会等待一个额外的帧。结果是帧速率下降到略高于指定速率的一半。在 20 或 30 fps 下,您可能根本不会注意到这一点,因为它可以很好地对齐。
例如,假设 Chrome 跳到 80fps,而您在 RAF_SYNC 模式下的目标是 60fps:
- Chrome 触发英国皇家空军事件。
- Ticker 查看自上次报价以来经过的时间,发现它只有 12 毫秒,认为它还不够接近其 16.67 毫秒的目标,并等待下一个 RAF 事件
- Chrome 触发另一个 RAF 事件。
- Ticker 查看并看到自上次滴答以来已经过去了超过 16.67 毫秒,并立即触发滴答,但此时已经过去了 25 毫秒。
- 重复。您现在 运行 为 ~40fps 而不是 60fps,即使实际帧速率为 ~80fps。
我希望这是有道理的。