簡體   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