【发布时间】:2017-04-29 01:41:00
【问题描述】:
看看我的游戏的运动功能:
https://jsfiddle.net/qk7ayx7n/92/
var canvas = document.getElementById("canvas");
var ctx=canvas.getContext("2d");
height = window.innerHeight;
canvas.width = window.innerWidth;
canvas.height = height;
playerY = height / 2;
playerX = 50;
var circle = new Image();
circle.src = "https://s21.postimg.org/4zigxdh7r/circ.png";
ctx.drawImage(circle, playerX, playerY);
move();
function move(){
velocity = height * 0.00050; // the velocity should be proptional to screen height.
startPos = playerY,
endPos = 0,
distanceY = endPos - playerY,
startTime = Date.now(),
duration = Math.abs(distanceY) / velocity;
requestAnimationFrame(startMoving);
function startMoving(){
var elapsedTime = Math.min(Date.now() - startTime, duration),
cbEnd = false;
if (elapsedTime < duration){ //time's up
setTimeout(function() {
requestAnimationFrame(startMoving);
}, 1000 / 60);
}
else cbEnd = true;
playerY = startPos - (elapsedTime * velocity);
console.log(playerY);
ctx.clearRect(0, 0, window.innerWidth, height);
ctx.drawImage(circle, playerX, playerY); //drawing circle
if(cbEnd) console.log("over");
}
}
现在,我将解释:我的实际游戏是玩家的速度随着游戏的进行而变化的游戏。速度与窗口的高度成正比,因为玩家的目标是向上移动。 我使用this technique 是为了更好地控制我执行的玩家抽签次数。我们稍后会解决这个问题。
我还使用this technique(见答案)来测量时间,以防最后一帧有延迟,它只会覆盖它应该覆盖的距离,这也意味着目标 Y在所有设备上始终准时到达。
FPS 平均值是我遇到的最大问题。不同的设备有不同的规格。为了打造适合所有设备的好游戏,我必须掌握这个功能:
setTimeout(function() {
var fps = 60;
requestAnimationFrame(startMoving);
}, 1000 / fps);
我已经在许多设备上测试了我的游戏,在某些设备上,fps 需要为 40、50、30 或其他一些设备才能使游戏顺利运行(这意味着每个玩家的“移动”将与之前的相同,否则他们会遇到滞后)。所以我在想,要么在游戏第一次“加载”时偷偷运行游戏并找出平均 FPS,要么保持某种学习曲线以调整此功能的运行次数。 无论哪种方式,我都不知道如何完美地实现它,我知道这可能很难,但我需要一些帮助。
【问题讨论】:
-
requestAnimationFrame 的回调以高精度返回时间,以毫秒为单位 1/1,000,000 秒 1/1,000(最小增量 0.001 毫秒)将其用于您的计时数据。例如
reaquestAnimatFrame(myLoop); function myLoop(timeInMS){Appart from that 我不确定你在问什么? -
如何根据通常发生的平均时间(通过测量以前的调用)知道调用 requestAnimationFrame 的确切时间,因此调整 setTimeout 以仅在安全时触发说不会有滞后。我基本上想实现彼此相等的动作,没有突然的“尖峰”。
-
requestAnimationFrame (rAF) 与显示刷新同步。只要您的动画渲染时间低于 1/60 秒,它就会以 60fps 的速度触发。但是,如果您超过 1/60 秒,则 rAF 将等到下一次显示刷新,帧速率为 30fps。在那之后20fps。如果您想保持帧速率,您可以忽略早期的 rAF 调用并在不渲染的情况下退出,仅在所需速率的帧上渲染。
-
我的建议是将你的动画绑定到时间而不是 FPS,那么 FPS 就无关紧要了(而不是运动/帧,考虑运动/时间等)。这样,画布就成为了场景中的“相机”和对象,而与画布显示/更新场景的频率无关。
标签: javascript html performance canvas