键盘输入暂停

时间:2019-04-16 19:54:29

标签: javascript input

我做了一个非常基本的演示,您按箭头键,正方形朝该方向移动。一个问题:当我第一次按下该键时,方块会移动一点,停顿一下,然后继续移动。如何摆脱或解决暂停问题?

代码:

    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>

1 个答案:

答案 0 :(得分:1)

发生这种情况是因为keydown事件是continuously fired at different intervals in different browsers

与其依赖浏览器不定期发送keydown,而是最好使用requestAnimationFrame60fps上运行自己的更新循环,并逐帧移动框在按下的键上。

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