I'm trying to provide a way for a user to map custom keys for a JavaScript game I'm working on. I think I'm just missing something simple here as I can't see how to make this work without looping over each key value (something I want to avoid as I don't want to introduce any unnecessary loops while still providing flexibility).
Basically, there is a global array keys
which tracks the keys that have been pressed to easily allow multiple keypresses to be handled simultaneously.
// keyboard lookup
// map movement keys to WASD, VI keys, and arrow keys
let keyboardConfig = {
'left': [37, 72, 65],
'right': [39, 76, 68],
'up': [38, 75, 87],
'down': [40, 74, 83],
'upleft': [89],
'upright': [85],
'downleft': [66],
'downright': [78]
}
And the keyboard handler:
// handle keyboard
let keys;
function handleKeys(e) {
keys = (keys || []);
keys[e.keyCode] = true;
let dirX = 0;
let dirY = 0;
let updateViz = false;
// TBD: replace keys[37] (etc.) with a more intelligent approach
if (keys[37]) { // left
dirX = -1;
updateViz = true;
}
if (keys[38]) { // up
dirY = -1;
updateViz = true;
}
if (keys[39]) { // right
dirX = 1;
updateViz = true;
}
if (keys[40]) { // down
dirY = 1;
updateViz = true;
}
if (updateViz) {
player.move(dirX, dirY);
camera.update();
}
}
Basically, I want to avoid having to do something like a forEach
over every keyCode
defined in keyboardConfig.left
, for instance. On the other hand, I need to avoid doing something like if keys[keyboardConfig.left[0]] || keys[keyboardConfig.left[1]] || keys[keyboardConfig.left[2]]
as that clearly is not very extensible.
This is the general idea, if there are conditions you need to check against, you're almost always going to want maps to define what it is to do, then implement those maps as instructions - this is a start:
document.onkeyup = handleKeys;
let elExample = document.getElementById("example");
// keyboard lookup
// map movement keys to WASD, VI keys, and arrow keys
let keyboardConfig = {
'left': [37, 72, 65],
'right': [39, 76, 68],
'up': [38, 75, 87],
'down': [40, 74, 83],
'upleft': [89],
'upright': [85],
'downleft': [66],
'downright': [78]
}
let movement = {
'left': -1,
'right': 1,
'up': -1,
'down': 1
}
let keyConfig = {};
for(let item in keyboardConfig){
for(let i in keyboardConfig[item]){
keyConfig[keyboardConfig[item][i]] = item;
}
}
// handle keyboard
let keys;
function handleKeys(e) {
console.log(e.keyCode)
keys = (keys || []);
keys[e.keyCode] = true;
if (keyConfig[e.keyCode]) {
console.log(keyConfig[e.keyCode], movement[keyConfig[e.keyCode]]);
elExample.innerHTML = keyConfig[e.keyCode] + " " + movement[keyConfig[e.keyCode]];
//player.move(movement[keyConfig[e.keyCode]] || 0, movement[keyConfig[e.keyCode]] || 0);
//camera.update();
}else{
elExample.innerHTML = "Not a tracked key";
}
}
<h4 id="example">type some stuff</h4>