Ive made a fairly simple movement script for a web based game I am making and I noticed that when a key is held down, it runs the movements once, waits a while, then starts moving continuously. I assume this is a thing that’s done by browsers to stop users from accidentally typing thousands of letters when holding a key down for too long, but is there any way to disable this?
This is a method used in my "Game" class which has all the functions needed for the game too run
movement(player) {
let movements = {
up: false,
down: false,
left: false,
right: false,
speed: 0,
maxSpeed: 10,
lastMove: null
}
function controls(e) {
const key = e.key;
if (key == "w") {
e.preventDefault();
movements.up = true;
}
if (key == "s") {
e.preventDefault();
movements.down = true;
}
if (key == "a") {
e.preventDefault();
movements.left = true;
}
if (key == "d") {
e.preventDefault();
movements.right = true;
}
}
function movement(x) {
let direction = null;
if (movements.up) direction = "up";
else if (movements.down) direction = "down";
else if (movements.left) direction = "left";
else if (movements.right) direction = "right";
if (direction) {
if (direction == "up" || direction == "down") {
player.src = `${x.data.entities.player.image}${direction}.png`;
player.style.top = `${parseInt(player.style.top) + (direction == "up" ? -1 : 1) * movements.speed}px`;
} else {
player.src = `${x.data.entities.player.image}${direction}.png`;
player.style.left = `${parseInt(player.style.left) + (direction == "left" ? -1 : 1) * movements.speed}px`;
}
movements.lastMove = direction;
}
if (direction && movements.speed < movements.maxSpeed) {
movements.speed++;
}
if (direction) {
movements.up = false;
movements.down = false;
movements.left = false;
movements.right = false;
}
requestAnimationFrame(() => movement(x));
}
requestAnimationFrame(() => movement(this));
document.addEventListener("keydown", (e) => {
controls(e);
});
}
2
Answers
A well known approach to minimize the dependency on OS and hardware is to handle yourself the keys state (up or down). Then you can just tell when key is down by looking at this dictionary object.
How to ignore keyboard auto repetition
Settings for keyboard auto repeat functionality are managed by the O/S, and can’t be set in JavaScript from within a browser.
Note auto repetition of keys that have been held down causes additional
keydown
events to be fired in the browser – with nokeyup
events between them.Hence to ignore repeated keys, disable
keydown
event handling at the end of thekeydown
handler, and re-enable it in akeyup
handler added for that purpose, along the lines of:Concept demonstration: