繁体   English   中英

如何阻止按钮被按下两次

[英]how to stop a button from being pressed twice

所以我正在制作一个神,如果你点击回车,它会发射一个炮弹,回车按钮会增加球的速度。 问题是当我多次点击进入时,我不知道如何制作,以至于人们无法多次点击它以使大炮超快。 我也不知道如何点击按钮进入,所以我只是使用向上箭头。

document.onkeydown = (e) => {
  e.preventDefault();

  if (e.repeat) return; // Do nothing

  const { key } = e;

  switch(key) {
    case 'ArrowUp':
      cannonball.dx++,
      cannonball.dy++
      break;
  }
};

这是我正在使用它的东西

const c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//variables
const cannon = {
w: 150,
h: 75,
x:0,
y:0
}

const cannonball = {
x: 77,
y: 565,
r:25,
dx:0,
dy:0
}

const cannonRotate = {
degree: -43.5
}



//running the whole function
function animate(){
c.clearRect(0,0,innerWidth,innerHeight);
//cannon
c.save();
c.translate(-25,600);
c.rotate(cannonRotate.degree * Math.PI / 180);
c.fillStyle = '#000';
c.fillRect(cannon.x,cannon.y,cannon.w,cannon.h);
c.restore();

//cannonball
c.beginPath();
c.arc(cannonball.x,cannonball.y, cannonball.r, 0, Math.PI * 2, false);
c.fillStyle = '#000';
c.fill();

cannonball.x += cannonball.dx;
cannonball.y -= cannonball.dy;



document.onkeydown = (e) => {
  e.preventDefault();

  if (e.repeat) return; // Do nothing

  const { key } = e;

  switch(key) {
    case 'ArrowUp':
      cannonball.dx += 5,
      cannonball.dy += 5
      break;
  }
};

requestAnimationFrame(animate)
}

如果我正确理解了您的问题,您想限制按键之间的间隔,对吗? 因此,您可以通过实现一个计时器来做到这一点,该计时器在完成之前忽略下一次按键:

let ignoreKeyPress = false;

document.onkeydown = (e) => {
  e.preventDefault();

  if (e.repeat || ignoreKeyPress) return; // Do nothing

  ignoreKeyPress = true;
  setTimeout(() => ignoreKeyPress = false, 1000); // change the 1000 to the interval between keypresses that you want in miliseconds.

  const { key } = e;

  switch(key) {
    case 'ArrowUp':
      cannonball.dx++,
      cannonball.dy++
      break;
  }
};

有很多方法可以做到这一点,但这里有一个节流示例,您可以尝试将其应用于您的代码。 这个想法是用一个包含上次调用时间的闭包来包装 function。 对于重复调用,在重新调用 function 之前检查最后一次。 cooldown变量确定允许重新触发之前的延迟时间(以毫秒为单位)。 这是一个通用的 function,您几乎可以应用于任何事情(例如,HTTP 请求以强制执行速率限制)。

除此之外,在 animation 循环中重新注册事件处理程序可能是一个错误。 这应该是一次性的设置任务,而不是您想要每秒执行 30-60 次的任务。

至于你要节流的东西,炮弹只有在按下箭头键时才会移动是不寻常的。 对于下面的最小示例,我正在限制发射率,这(可能?)对游戏更有意义。

 const throttle = (fn, cooldown=1000) => { let lastCall = 0; return (...args) => { if (Date.now() - lastCall > cooldown) { lastCall = Date.now(); fn(...args); } }; }; const canvas = document.createElement("canvas"); document.body.appendChild(canvas); const ctx = canvas.getContext("2d"); canvas.width = innerWidth; canvas.height = innerHeight; ctx.fillStyle = "#000"; const cannonBalls = []; (function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (const e of cannonBalls) { e.dx *= 0.99; e.dy += 0.1; ex += e.dx; ey += e.dy; ctx.beginPath(); ctx.arc(ex, ey, e.r, 0, Math.PI * 2); ctx.fill(); } requestAnimationFrame(animate); })(); const fire = throttle(() => cannonBalls.push({ x: 10, y: 10, dx: 10, dy: 0, r: 10 })); document.addEventListener("keydown", e => { if (e.keyCode === 32) { e.preventDefault(); .e;repeat && fire(); } });
 <p>press spacebar to fire</p>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM