UNPKG

blob2d

Version:

Typed Modular 2D Game Engine for Web

61 lines (47 loc) 1.44 kB
import {refineArray} from '../utils/array'; type TEventCallback = (pressed: boolean) => void; export class Keyboard<TKey extends string = string> { public readonly destroy: () => void; protected states: Map<TKey, boolean>; protected events: Map<TKey, TEventCallback>; constructor() { this.states = new Map(); this.events = new Map(); const listener = (event: KeyboardEvent) => { this.handleEvent(event); }; window.addEventListener('keydown', listener); window.addEventListener('keyup', listener); this.destroy = () => { window.removeEventListener('keydown', listener); window.removeEventListener('keyup', listener); this.events.clear(); }; } public on(keys: TKey | TKey[], callback: TEventCallback) { refineArray(keys).forEach(key => { this.events.set(key, callback); }); } public off(keys: TKey | TKey[]) { refineArray(keys).forEach(key => { this.events.delete(key); }); } protected handleEvent(event: KeyboardEvent) { event.preventDefault(); const key = event.key as TKey; if (!this.events.has(key)) { return; } const pressed = event.type === 'keydown'; // shouldn't invoke keyup before keydown if (!pressed && !this.states.get(key)) { return; } if (this.states.get(key) !== pressed) { this.states.set(key, pressed); this.events.get(key)?.(pressed); } } }