Inleiding

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!");
});

Constants

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;

Keyboard Class

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.

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);
    }
}

Instance