import { InputHandler } from './inputhandler'; import { Listenable } from '../../util'; import { vec2 } from 'gl-matrix'; export enum ButtonCode { Action, Back, Menu, } const buttonMapping: {[key: string]: ButtonCode} = { KeyZ: ButtonCode.Action, KeyX: ButtonCode.Back, KeyC: ButtonCode.Menu, }; export interface DirectionInput { type: 'direction'; direction: vec2; } export interface ButtonInput { type: 'button'; button: ButtonCode; } export type GameInput = DirectionInput | ButtonInput; export class GameInputHandler extends Listenable<[GameInput]> { private readonly input: InputHandler; constructor() { super(); this.input = new InputHandler( new Set([ 'ArrowLeft', 'ArrowUp', 'ArrowRight', 'ArrowDown', ...Object.keys(buttonMapping), ])); this.input.addListener((key: string, pressed: boolean) => { const button = buttonMapping[key]; if (button !== undefined) { if (pressed) this.runListeners({ type: 'button', button, }); return; } const dir = vec2.create(); if (this.input.has('ArrowLeft')) vec2.add(dir, dir, [-1, 0]); if (this.input.has('ArrowUp')) vec2.add(dir, dir, [0, -1]); if (this.input.has('ArrowRight')) vec2.add(dir, dir, [1, 0]); if (this.input.has('ArrowDown')) vec2.add(dir, dir, [0, 1]); if (vec2.sqrLen(dir) > 0) vec2.normalize(dir, dir); this.runListeners({ type: 'direction', direction: dir, }); }); } }