Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript requestAnimationFrame不';按键保持时不会重新触发,但设置超时会重新触发_Javascript_Events_Requestanimationframe - Fatal编程技术网

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()