我做了一个非常基本的演示,您按箭头键,正方形朝该方向移动。一个问题:当我第一次按下该键时,方块会移动一点,停顿一下,然后继续移动。如何摆脱或解决暂停问题?
代码:
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext('2d');
var p1 = document.getElementById("p1");
var keys = [];
var x = 25
var y = 25
document.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
update();
});
document.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
update();
});
function update() {
ctx.clearRect(0, 0, 400, 400)
if(keys[40] == true) {
y += 5
}
if(keys[38] == true) {
y -= 5
}
if(keys[39] == true) {
x += 5
}
if(keys[37] == true) {
x -= 5
}
ctx.fillRect(x, y, 100, 100)
console.log(keys);
p1.innerText = "";
for (i = 0; i < keys.length; i++) {
if (keys[i]) {
p1.innerText += i + " | ";
}
}
}
<canvas id='canvas' width='400' height='400'></canvas>
<p id='p1'>testing</p>
答案 0 :(得分:1)
发生这种情况是因为keydown
事件是continuously fired at different intervals in different browsers。
与其依赖浏览器不定期发送keydown
,而是最好使用requestAnimationFrame在60fps
上运行自己的更新循环,并逐帧移动框在按下的键上。
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext('2d');
var p1 = document.getElementById("p1");
var keys = [];
var x = 25
var y = 25
document.addEventListener("keydown", function(e) {
e.preventDefault(); // make sure this doesn't scroll the window
keys[e.keyCode] = true;
});
document.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
});
function update() {
// Tell the browser to run again update when it is "free",
// preferably at 60fps (actually your monitor's refresh rate)
requestAnimationFrame(update);
ctx.clearRect(0, 0, 400, 400)
if(keys[40] == true) {
y += 5
}
if(keys[38] == true) {
y -= 5
}
if(keys[39] == true) {
x += 5
}
if(keys[37] == true) {
x -= 5
}
ctx.fillRect(x, y, 100, 100)
p1.innerText = "";
for (i = 0; i < keys.length; i++) {
if (keys[i]) {
p1.innerText += i + " | ";
}
}
}
update(); // Start running the loop at 60fps
<canvas id='canvas' width='400' height='400'></canvas>
<p id='p1'>testing</p>
请注意,距离框会在给定的时间内移动取决于您的帧速率,因此,如果浏览器无法保持60fps
并且仅在30fps
运行,update
只会被调用一半的时间,因此该框将只移动其在60fps
处移动一半的距离。要了解有关动画和游戏更新循环的更多信息,我建议阅读此fix your timestep article。