How do I hold an action key until I release the key

Asked

Viewed 642 times

8

In video game games the action displayed when pressing a key is smooth, continuous and immediate.
However when implementing a routine that animates a character according to the key pressed using the event onkeydown she is not continuous, the animation of the character suffers one intermittence and does not work well the diagonals. For example:

/**movimente com as setas direcionais do teclado**/
let player = document.querySelector('#player');
let x = 0;
let y = 0;

let velocidade = 3;

window.onkeydown = () => {
  let key = event.keyCode;
  let velocity = 10;
  let pixel = "px";

  //Detecta qual tecla do direcional do teclado foi pressionada e calcula um deslocamento absoluto 
  if (key == 37) x -= velocidade;
  if (key == 38) y -= velocidade;
  if (key == 39) x += velocidade;
  if (key == 40) y += velocidade;

  //Reposiciona o personagem
  player.style.left = x + "px";
  player.style.top = y + "px";

}
body {
  background: #a7a7a7;
}

#player {
  width: 50px;
  height: 50px;
  background: #505050;
  position: relative;
  left: 0;
  top: 0;
}
<div id="player"></div>

I want to know how to make animation via keyboard events be fluid just like video games.

1 answer

10


In fact the code presents two immediate problems:

  • The manipulation of keyboard events in the way that is done is not the most efficient to obtain the desired effect. Works well for web applications but not for games.
  • If the animation aims games, it must be done within an animation loop and must make use of a graphical API.

Movements

In the case of a keyboard-sensitive animation the detection of the keys and displacement of the action target must not necessarily occur together, preferably separate events and be processed as distinct activities.

Uses both of these events keydown and keyup together.

  • keydown to check and inform the system if a certain key has been pressed and nothing more!
  • keyup to check and inform the system if a certain key has been released and nothing more!

Graphics

As for the graphical API Javascript natively provides two interfaces to Canvas API to work with raster and the SVG API to work with vector graphics.

To display the graphics the Canvas API will be used through the element HTML <canvas> which is the element HTML used to draw graphs via script.
To use graphical methods on <canvas> it is first necessary to obtain the graphic context which methods will be applied, whether it is a 2D/3D display context or whether the context is memory, to obtain the graphic context it is used the method HTMLCanvasElement.getContext().

To animate the graphics it is necessary to inform the browser that you want to carry out an animation and ask the browser to call a specific function to update an animation frame before the next repeat of the interface using the method window.requestAnimationFrame().

Example:

/**movimente com as setas direcionais do teclado**/

//Os estados das teclas a serem usados durante um frame de animação
let up = false;
let down = false;
let left = false;
let right = false;

//A posição do personagem na tela
let pos = {
  x: 0,
  y: 0
};

let lado = 50; //Medida da lateral do personagem(retângulo no caso)
let velocidade = 3; //Velocidade de deslocamento do personagem

let canvas; //Elemento canvas 
let ctx; //Contexto gráfico do canvas

//Ao carregar a página...
window.addEventListener("load", () => {
  //Obtém o canvas e contexto gráfico
  canvas = document.getElementById("canvas");
  ctx = canvas.getContext("2d");

  //Quando pressionada uma tecla específica sinaliza o seu estado como pressionado
  document.addEventListener("keydown", (event) => {
    if (event.key == "ArrowUp") up = true;
    if (event.key == "ArrowDown") down = true;
    if (event.key == "ArrowLeft") left = true;
    if (event.key == "ArrowRight") right = true;
  });

  //Quando solta um tecla específica sinaliza o seu estado como não pressionado
  document.addEventListener("keyup", (event) => {
    if (event.key == "ArrowUp") up = false;
    if (event.key == "ArrowDown") down = false;
    if (event.key == "ArrowLeft") left = false;
    if (event.key == "ArrowRight") right = false;
  });

  //Inicia o loop de animação.
  requestAnimationFrame(frame);
});

//A cada frame de animação
function frame() {
  //Para cada uma das teclas do direcional verifica se estiver pressionada aplica um deslocamento
  if (up) pos.y -= velocidade;
  if (down) pos.y += velocidade;
  if (left) pos.x -= velocidade;
  if (right) pos.x += velocidade;

  ctx.clearRect(0, 0, canvas.width, canvas.height); //Limpa a tela
  ctx.fillStyle = "rgb(200,0,0)"; //Seta a cor do desenho como vermelho
  ctx.fillRect(pos.x, pos.y, lado, lado); //Desenha o personagem tela(um retângulo)
  requestAnimationFrame(frame); //Faz a solicitação de um novo quadro de animação

}
<!--Para animações mais performáticas use o elemento canvas-->
<canvas id="canvas"></canvas>

  • 1

    Excellent!!!! = D

  • 1

    Great answer! thanks for your attention.

Browser other questions tagged

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