0

In this game I'm making, whenever I move my character, it only takes one step, pauses, and then keeps moving. Example: if I hold a button to move it will go the 2.5 units in whatever direction, pause for about 1/2 a second, and then continue to move for as long as I am holding down the button.

Here is the relevent code:

addEventListener('keydown',function(action){
    var c = document.getElementById("canvas");
    var ctx = c.getContext("2d");
    
    if (action.code == "KeyD" || action.code == "ArrowRight" ){
        ui.image_x = 192;
        ui.hero.position.x = ui.hero.position.x + 2.5;
        ui.update();
        ui.draw();
        ui.draw_sprite();
    }
    if (action.code == "KeyA" || action.code == "ArrowLeft" ){
        ui.image_x = 288;
        ui.hero.position.x = ui.hero.position.x - 2.5;
        ui.update();
        ui.draw();
        ui.draw_sprite();
    }
    if (action.code == "KeyW" || action.code == "ArrowUp" ){
        ui.image_x = 128;
        ui.hero.position.y = ui.hero.position.y - 2.5;
        ui.update();
        ui.draw();
        ui.draw_sprite();
    }
    if (action.code == "KeyS" || action.code == "ArrowDown" ){
        ui.image_x = 32;
        ui.hero.position.y = ui.hero.position.y + 2.5;
        ui.update();
        ui.draw();
        ui.draw_sprite();
    }
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 3
    Without an example of the problem ([mre]), there's no way we can answer this. – DBS Mar 24 '23 at 10:46
  • Sounds like the normal input delay that occurs when holding a key, I'm not sure if you can "disable" that from JavaScript. – Mark Rotteveel Mar 27 '23 at 09:11
  • 1
    There is **exactly** the same question, already answered: https://stackoverflow.com/questions/12273451/how-to-fix-delay-in-javascript-keydown – novarx Mar 28 '23 at 07:59
  • Does this answer your question? [How to fix delay in javascript keydown](https://stackoverflow.com/questions/12273451/how-to-fix-delay-in-javascript-keydown) – Brandon Gano Mar 28 '23 at 08:39

1 Answers1

2

As @MarkRotteveel mentioned in the comment above, what you're noticing is a built-in delay browsers use to prevent accidental typos. If you press and hold a letter key while in a textbox, you'll see the same delay after the first character.

The only way I'm aware of to get around this is to use a more traditional "game loop". Here's the basic idea:

  • Use the keydown event to detect and store pressed arrow keys.
  • Use requestAnimationFrame to move the character when an arrow key is pressed.
  • Use the keyup event to stop moving.

Here's an example:

var moveRight = false;
var moveLeft = false;
var moveUp = false;
var moveDown = false;

// Detect when movement keys are pressed
addEventListener("keydown", function (action) {
  if (action.code === "KeyD" || action.code === "ArrowRight") {
    moveRight = true;
  }
  if (action.code === "KeyA" || action.code === "ArrowLeft") {
    moveLeft = true;
  }
  if (action.code === "KeyW" || action.code === "ArrowUp") {
    moveUp = true;
  }
  if (action.code === "KeyS" || action.code === "ArrowDown") {
    moveDown = true;
  }
});

// Detect when movement keys are released
addEventListener("keyup", function (action) {
  if (action.code === "KeyD" || action.code === "ArrowRight") {
    moveRight = false;
  }
  if (action.code === "KeyA" || action.code === "ArrowLeft") {
    moveLeft = false;
  }
  if (action.code === "KeyW" || action.code === "ArrowUp") {
    moveUp = false;
  }
  if (action.code === "KeyS" || action.code === "ArrowDown") {
    moveDown = false;
  }
});

// Move the character (if necessary)
function moveCharacter() {
  if (moveRight && !moveLeft) {
    ui.image_x = 192;
    ui.hero.position.x = ui.hero.position.x + 2.5;
    ui.update();
    ui.draw();
    ui.draw_sprite();
  }
  else if (moveLeft && !moveRight) {
    ui.image_x = 288;
    ui.hero.position.x = ui.hero.position.x - 2.5;
    ui.update();
    ui.draw();
    ui.draw_sprite();
  }
  if (moveUp && !moveDown) {
    ui.image_x = 128;
    ui.hero.position.y = ui.hero.position.y - 2.5;
    ui.update();
    ui.draw();
    ui.draw_sprite();
  }
  else if (moveDown && !moveUp) {
    ui.image_x = 32;
    ui.hero.position.y = ui.hero.position.y + 2.5;
    ui.update();
    ui.draw();
    ui.draw_sprite();
  }
  requestAnimationFrame(moveCharacter); // Continue the game loop
}
moveCharacter(); // Start the game loop

The checks above like moveLeft && !moveRight make sure the user isn't trying to move in two opposing directions at once.

Brandon Gano
  • 6,430
  • 1
  • 25
  • 25