Search code examples
javascriptkeydownkeyevent

JS Always check keydown


I'm building a 3D FPS game with Three.js.

When I use a full auto weapon, I want it to continuously fire from the second you hold down the "f" key.

But instead JS detects the first keydown event, delays it for a second, and then detects the rest of them.

Kind of like this:

keydown>

"f" key detected...

(1 second delay)

"f" key detected...
"f" key detected...
"f" key detected...
"f" key detected...
"f" key detected...

I assume you understand my point by now.

How can I always detect keydown events without a delay?

Note that I'm using the usual document.addEventListener("keydown", ...) for it.

Preview

https://i.imgur.com/ro1HZWQ.mp4

Edit: Some of you have been asking for code.

document.addEventListener("keydown", (e) => {
  if (e.key == "f") {
    fire(1);
    // Since "!e.repeat" is not included, it will fire 1 round every time the key event is detected, and stop when the key goes up.
  }
});

Expected behaviour:

keydown>

"f" key detected...
"f" key detected...
"f" key detected...
"f" key detected...
"f" key detected...
"f" key detected...

Actual behaviour:

keydown>

"f" key detected...

(1 second delay)

"f" key detected...
"f" key detected...
"f" key detected...
"f" key detected...
"f" key detected...

Solution

  • I asume you are firing on each keydown event, while you should actually togge an isFiring variable to "on/true" on keydown, and toggle it to "off/false" on keyup:

    const conDiv = document.getElementById('continuous');
    const onDiv = document.getElementById('onKeyDown');
    let isFiring = false;
    
    let isFiringShots = 0;
    let onKeyDownShots = 0;
    
    function render() {
      conDiv.innerHTML = `Shots using "isFiring" variable fired: ${isFiringShots}`;
      onDiv.innerHTML = `Shots using "keydown" fired: ${onKeyDownShots}`;
    }
    
    setInterval(() => {
      render();
      if (isFiring) {
        isFiringShots += 1;
      }
    }, 50);
    
    document.addEventListener('keydown', (e) => {
      if (e.keyCode == 74) {
        onKeyDownShots += 1;
        isFiring = true;
      }
    });
    
    document.addEventListener('keyup', (e) => {
      if (e.keyCode == 74) {
        isFiring = false;
      }
    });
    <h2>Click here and press "j"</h2>
    
    <div id="continuous">Shots using `isFiring` variable fired: 0</div>
    
    <div id="onKeyDown">Shots using `keydown` fired: 0</div>