所以我正在制作一个javascript游戏。我有这个基本的游戏循环引擎。
var left = 0,
speed = documentHeight/300;
var keyState = {};
window.addEventListener('keydown',function(e){
keyState[e.keyCode || e.which] = true;
},true);
window.addEventListener('keyup',function(e){
keyState[e.keyCode || e.which] = false;
},true);
function gameLoop() {
if (keyState[39]) {
left -= speed;
move();
}
if (keyState[37]){
left += speed;
move();
}
function move() {
element.style.left = left + 'px';
}
setTimeout(gameLoop, 20);
}
gameLoop();
我拥有100%高度的全部因此我相对于文档高度设置了速度。它在我的电脑上运行得很好,即使在调整大小时它也是一致的。但是当我在iMac上测试它时,元素移动得慢得多。我也尝试过window.requestAnimationFrame(gameLoop),但同样的事情发生了。
这是否与处理更多fps的某些屏幕有关?在所有计算机/屏幕上实现一致速度的最佳方法是什么?
答案 0 :(得分:2)
每帧20毫秒,即50 fps。这不是超高,但它可以在较慢的计算机上放慢速度(因为它无法跟上)。
更安全的方法是仍以所需的帧速率运行它,然后检查帧之间的时间差值,并根据经过的实际时间进行移动,而不是假设一个恒定的FPS。
这样做的简单方法就是记录每个循环的最后一次,然后从当前时间中减去并根据时间量按某种因素缩放,例如:
所以我正在制作一个javascript游戏。我有这个基本的游戏循环引擎。
var left = 0,
speed = documentHeight/300,
lastTime = Date.now();
var keyState = {};
window.addEventListener('keydown',function(e){
keyState[e.keyCode || e.which] = true;
},true);
window.addEventListener('keyup',function(e){
keyState[e.keyCode || e.which] = false;
},true);
function gameLoop() {
const currentTime = Date.now();
const delta = currentTime - lastTime;
lastTime = currentTime;
if (keyState[39]) {
left -= speed * delta;
move();
}
if (keyState[37]){
left += speed * delta;
move();
}
function move() {
element.style.left = left + 'px';
}
setTimeout(gameLoop, 20);
}
gameLoop();
然后,只需设置"速度"相对于每毫秒的值(例如每毫秒5px,或每毫秒屏幕高度的0.00033%)。通过这样做并乘以经过的时间,即使您的实际循环速度不是非常一致,您也可以获得更平稳的移动。
附加说明:有时,根据您的应用程序,您可能还想跟踪剩余部分。如果您正在做类似"每秒10px",但已经过了20ms,那就是10 / 1000 * 20 = 0.2px
。由于您无法实际移动.2px,因此您可能需要跟踪剩余部分并将其重新添加到下一个循环中。
或者,您可以让您的位置为小数,并在draw()阶段解决它。这可能是一种更清洁的方法,而且我通常采用这种方法。