Javascript requestAnimationFrame不';按键保持时不会重新触发,但设置超时会重新触发
我得到的印象是,Javascript requestAnimationFrame不';按键保持时不会重新触发,但设置超时会重新触发,javascript,events,requestanimationframe,Javascript,Events,Requestanimationframe,我得到的印象是,setTimeOut不好,requestAnimationFrame好。因此,我尽职尽责地重构: document.addEventListener( 'keydown', function ( e ) { var key = e.keyCode; if ( key === 70 && go_up === false && gameOver === false ) { go_up = setInterval( up, 50
setTimeOut
不好,requestAnimationFrame
好。因此,我尽职尽责地重构:
document.addEventListener( 'keydown', function ( e ) {
var key = e.keyCode;
if ( key === 70 && go_up === false && gameOver === false ) {
go_up = setInterval( up, 50 );
}
} );
进入
在第一个版本中,如我所愿,按住键会不断重新触发回调。requestTimeOut
版本不存在
如何使
requestTimeOut
版本的行为与setTimeOut
版本的行为相似?如果您正在构建游戏,最好将游戏循环保留在其自身的功能中,而不是在按钮处理程序中调用(并停止)游戏循环。在大多数游戏中,游戏循环总是运行的,因为总有一些事情发生(敌人移动、记分板更新等)
这就是为什么requestAnimationFrame
非常棒的原因,如果用户在游戏运行时单击另一个选项卡,它将不会限制您的CPU
在这里扩展一下Randy的答案:
let speed = 0
let box = document.querySelector("#box")
function setupGame(){
document.addEventListener('keydown', (e) => checkInput(e))
gameLoop()
}
function checkInput(e){
if (e.key.toLowerCase() === 'f') {
speed = 10
}
// more keyboard checks here
}
function gameLoop() {
let rect = box.getBoundingClientRect();
box.style.transform = "translateX(" + (rect.left + speed) + "px)";
requestAnimationFrame(()=>gameLoop())
}
setupGame()
它们(setInterval、requestAnimationFrame)做不同的事情。第一个版本创建了很多很多间隔计时器。第二个创建了很多很多超时计时器。第一个每隔50毫秒设置一次间隔,而第二个每隔20毫秒设置一次超时。这两段代码之间有很多不同之处。您根本不可能需要调用
setTimeout()
。但这取决于你的意图是否是节流。我看到fps和微秒的问题。我确实需要对帧速率进行精确控制。删除对setTimeout()
的调用,然后在那里使用requestAnimationFrame()
。这段代码很容易给你60帧。我不明白-我以为requestAnimationFrame不允许你指定帧速率?你也不能用定时器指定帧速率。它们并不精确。
let speed = 0
let box = document.querySelector("#box")
function setupGame(){
document.addEventListener('keydown', (e) => checkInput(e))
gameLoop()
}
function checkInput(e){
if (e.key.toLowerCase() === 'f') {
speed = 10
}
// more keyboard checks here
}
function gameLoop() {
let rect = box.getBoundingClientRect();
box.style.transform = "translateX(" + (rect.left + speed) + "px)";
requestAnimationFrame(()=>gameLoop())
}
setupGame()