Javascript:限制按下按键事件监听器在按下时可以多快调用一次函数

时间:2019-03-08 03:01:30

标签: javascript canvas event-handling

我正在开发基于JavaScript的游戏,目前正在研究游戏角色移动和动画。当玩家在keydown事件期间按下控件(WASD)时,将对此进行控制。我的问题是,按下并按住这些键时,调用处理程序的速度太快,这使我的游戏角色/精灵看起来像是他的癫痫发作(因为它在精灵图像中循环太快了)。

如何限制调用角色移动/动画行为的速度?我的代码当前如下所示:

let canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
let xPos = 10
let yPos = 10
document.addEventListener('keydown', movement)

function movement(e){
//Player Controls 
// horizontal and vertical movement
    if (e.keyCode === 87 ){
         ctx.clearRect(0,0, canvas.width, canvas.height);
         y=y-3;
         sY = 97
         runningMan();
    }
     if(e.keyCode === 83){
        ctx.clearRect(0,0, canvas.width, canvas.height);
        y=y+3;
        sY = 0
        runningMan();
    }
    if(e.keyCode === 65){
        ctx.clearRect(0,0, canvas.width, canvas.height);
        x=x-3;
        sY = 32
        runningMan();
    }
    if(e.keyCode === 68){
        ctx.clearRect(0,0, canvas.width, canvas.height);
        x=x+3;
        sY = 64
        runningMan();
    }
  
 
    // keeping the player inside the canvas
    xPos = Math.min(Math.max(x, 0+5), canvas.width-10);
    yPos = Math.min(Math.max(y, 0+5), canvas.height-10); 
}

//img,SX,SY,SW,SH,DX,DY,DW,DH)
let img = new Image();
img.src = 'runningGood.png'
let cycle = 0
let sY;
let sW = 30 
let sH = 32
let x = 0
let y = 0
let increase = 0
// setInterval(runningMan, 200);
function runningMan(){
    ctx.clearRect(0,0,sW+increase,sH+increase);
    ctx.drawImage(img,cycle*sW,sY,sW,sH,x,y,70,70)
    cycle = (cycle + 1) % 3;
  }
<!DOCTYPE html>
    <html lang='en'>
        <head>
            <meta charset='UTF-8'>
            <script src='project.js' defer></script>
            <title>1045 Project</title>
        </head>
        <body>
            <canvas id='myCanvas' width='750' height ='750' style='border: 2px solid black'></canvas>
        </body>
    </html>

1 个答案:

答案 0 :(得分:0)

与您当前的代码集成在一起并避免使用第三方库的一种解决方案是添加以下内容:

this.props.inputList
let canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
let xPos = 10
let yPos = 10

/* Add: track state of current throttle timer */
let throttle;
/* Add: When keyup happens, just reset the throttle timer */
document.addEventListener('keyup', () => {
  if (throttle) {
    clearTimeout(throttle);
    throttle = null;
  }
})

document.addEventListener('keydown', movement)

function movement(e) {

  /* Add: only allow normal keypress processing if no throttle
  timer is currently active */
  if (!throttle) {

    //Player Controls 
    // horizontal and vertical movement
    if (e.keyCode === 87) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      y = y - 3;
      sY = 97
      runningMan();
    }
    if (e.keyCode === 83) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      y = y + 3;
      sY = 0
      runningMan();
    }
    if (e.keyCode === 65) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      x = x - 3;
      sY = 32
      runningMan();
    }
    if (e.keyCode === 68) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      x = x + 3;
      sY = 64
      runningMan();
    }


    // keeping the player inside the canvas
    xPos = Math.min(Math.max(x, 0 + 5), canvas.width - 10);
    yPos = Math.min(Math.max(y, 0 + 5), canvas.height - 10);


    /* Add: Start a "throttle" timer that prevents next keyboard processing
    until timer completed */
    throttle = setTimeout(() => {

      throttle = null;

    /* Your throttle interval - reduce/increase this number to suit you needs */
    }, 1000)
  }
}

//img,SX,SY,SW,SH,DX,DY,DW,DH)
let img = new Image();
img.src = 'https://via.placeholder.com/160'
let cycle = 0
let sY;
let sW = 30
let sH = 32
let x = 0
let y = 0
let increase = 0
// setInterval(runningMan, 200);
function runningMan() {
  ctx.clearRect(0, 0, sW + increase, sH + increase);
  ctx.drawImage(img, cycle * sW, sY, sW, sH, x, y, 70, 70)
  cycle = (cycle + 1) % 3;
}

这里的一般想法是在进行常规<!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <script src='project.js' defer></script> <title>1045 Project</title> </head> <body> <canvas id='myCanvas' width='750' height='750' style='border: 2px solid black'></canvas> </body> </html>处理之后启动throttle计时器。 keydown计时器基本上可以阻止/阻止相同的throttle处理(即游戏角色移动)在应用程序/事件循环的下一次迭代中立即发生(这是导致游戏不稳定的原因)字符)。

希望这会有所帮助!