Delay keydown event when holding down button

Asked

Viewed 117 times

1

I’m creating a pong using Jquery and I’m having trouble with the keydown event. I will control the player by the up and down arrow, but when I keep the button pressed, it has a delay between the first and second run.

JS:

$(document).keydown(function(e) {
    switch(e.which) {
        case 38:
          if ((topPlayerOne - 10) >= 0) {
            topPlayerOne = (topPlayerOne - 10);
            playerOne.css('top', topPlayerOne);
          }
        break;
        case 40:
          if ((topPlayerOne + 10) <= 170) {
            topPlayerOne = (topPlayerOne + 10);
            playerOne.css('top', topPlayerOne);
          }
        break;
        default: return;
    }
    e.preventDefault();

HTML:

<div id="pongTable">
  <div id="playerOne" class="player"></div>
  <div id="playerAI" class="player"/></div>
</div>

<div id="score">
  <div id="scorePlayerOne" class="score">0</div>
  <div id="scorePlayerAI" class="score">0</div>
</div>

1 answer

1


That way it won’t even work, the event keydown is only fired once when you press the key.

For convenience, your operating system has this mechanism that when you hold down some keys, it simulates the key being pressed several times then, but this is not the right way to work a game.

You should probably use the classic video game approach, and create a main loop that runs 30 or 60 times per second. In this loop you check which keys are pressed, and do the treatment accordingly.

For example:

// objeto contendo as teclas pressionadas
const keys = {
  up: false,
  down: false
}

// listener que captura quando as teclas são pressionadas
$(document).keydown(function(e) {
  switch(e.which) {
    case 38:
      keys.up = true;
      break;
    case 40:
      keys.down = true;
      break;
    }
})

// listener que captura quando as teclas são liberadas
$(document).keyup(function(e) {
  switch(e.which) {
    case 38:
      keys.up = false;
      break;
    case 40:
      keys.down = false;
      break;
    }
})

// loop principal do jogo
function mainLoop() {
  console.clear();

  if (keys.up) {
    // código para mover o jogador para cima aqui
    console.log('up')
  } else if (keys.down) {
    // código para mover o jogador para baixo aqui
    console.log('down')
  } else {
    // nenhuma tecla pressionada
    console.log('neutral')
  }
}

// invoca o loop principal a cada 15 milesimos
setInterval(mainLoop, 15)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.