De invoer van toetsaanslagen via het Keyboard, kan je opvangen met Javascript. Je gebruikt daar Keyboard-events voor, die je opvangt met een addEventListener. Er wordt dan “geluisterd” naar een bepaald KeyboardEvent en als het zich voordoet, dan kan je een functie aanroepen die de vervolgstappen afhandeld van wat er dan moet gebeuren.
window.addEventListener('keydown', (event) => {
console.log("Klik!");
});
In het voorbeeld hieronder ga ik gebruikmaken van een aantal constante variabelen die een getal als waarde hebben die gelijk staat aan de ASCII-code die vroeger gekoppeld was aan deze toetsen. het zou netjes zijn als je deze waarden in een apart bestand zou opslaan, bijvoorbeeld constants.js, om vervolgens met behulp van ESM import/export de waarde bloot te stellen aan de rest van je code. Ik heb dat nu niet gedaan, maar raad je aan om dat wel te oefenen.
const KEY_UP = 38;
const KEY_DOWN = 40;
const KEY_LEFT = 37;
const KEY_RIGHT = 39;
const KEY_CTRL_RIGHT = 17;
const KEY_CTRL_LEFT = -17;
const KEY_SPACE = 32;
const KEY_ENTER = 13;
const KEY_W = 6;
const KEY_S = 7;
const KEY_A = 8;
const KEY_D = 9;
Om code te clusteren die bij elkaar hoort, zou het netjes kunnen zijn om een aparte Class te schrijven die over Keyboard-zaken gaan. Het onderstaande voorbeeld maakt gebruik van een Class.
De constructor wordt uitgevoerd op het moment dat er een nieuw Keyboard wordt aangemaakt.
Er wordt een Set aangemaakt met de naam this.keys, een object dat enigszins lijkt op een array.
Er wordt een EventListener aangemaakt die gaat luisteren naar het Event “keydown”.
Er wordt een EventListener aangemaakt die gaat luisteren naar het Event “keyup”.
De functie keyDown zorgt voor de afhandeling voor als er een toets is ingedrukt.
De functie keyUp zorgt voor de afhandeling voor als er een toets is losgelaten.
De functie iskeyDown kan straks worden gebruikt om te controleren in de gameloop of een bepaalde toets momenteel is ingedrukt.
De functie iskeyUp kan straks worden gebruikt om te controleren in de gameloop of een bepaalde toets momenteel niet is ingedrukt. Eigenlijk is deze laatste functie redundant. Zoek dit laatste woord maar even op. ;-)
class Keyboard {
constructor() {
this.keys = new Set();
window.addEventListener('keydown', this.keyDown.bind(this));
window.addEventListener('keyup', this.keyUp.bind(this));
}
keyDown(event) {
console.log(`keyDown() ${event.code}`);
event.preventDefault();
switch (event.code) {
case 'ArrowUp': this.keys.add(KEY_UP); break;
case 'ArrowDown': this.keys.add(KEY_DOWN); break;
case 'ArrowLeft': this.keys.add(KEY_LEFT); break;
case 'ArrowRight': this.keys.add(KEY_RIGHT); break;
case 'ControlRight': this.keys.add(KEY_CTRL_RIGHT); break;
case 'KeyW': this.keys.add(KEY_W); break;
case 'KeyS': this.keys.add(KEY_S); break;
case 'KeyA': this.keys.add(KEY_A); break;
case 'KeyD': this.keys.add(KEY_D); break;
case 'ControlLeft': this.keys.add(KEY_CTRL_LEFT); break;
case 'Space': this.keys.add(KEY_SPACE); break;
default: console.log('unknown key down');
}
}
keyUp(event) {
console.log(`keyUp() ${event.code}`);
event.preventDefault();
switch (event.code) {
case 'ArrowUp': this.keys.delete(KEY_UP); break;
case 'ArrowDown': this.keys.delete(KEY_DOWN); break;
case 'ArrowLeft': this.keys.delete(KEY_LEFT); break;
case 'ArrowRight': this.keys.delete(KEY_RIGHT); break;
case 'ControlRight': this.keys.delete(KEY_CTRL_RIGHT); break;
case 'KeyW': this.keys.delete(KEY_W); break;
case 'KeyS': this.keys.delete(KEY_S); break;
case 'KeyA': this.keys.delete(KEY_A); break;
case 'KeyD': this.keys.delete(KEY_D); break;
case 'ControlLeft': this.keys.delete(KEY_CTRL_LEFT); break;
case 'Space': this.keys.delete(KEY_SPACE); break;
default: console.log('unknown key up');
}
}
isKeyDown(key) {
return this.keys.has(key);
}
isKeyUp(key) {
return !this.keys.has(key);
}
}