From 1712352d1c72628a045300fe922c82cd3214070a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 31 Oct 2018 10:52:57 +0100 Subject: view: add simple input handlers --- src/util.ts | 12 ++++++++++++ src/view/input/DirectionHandler.ts | 36 +++++++++++++++++++++++++++++++++++ src/view/input/InputHandler.ts | 39 ++++++++++++++++++++++++++++++++++++++ src/view/renderer/Renderer.ts | 6 +++++- 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/view/input/DirectionHandler.ts create mode 100644 src/view/input/InputHandler.ts (limited to 'src') diff --git a/src/util.ts b/src/util.ts index 453966e..7129b2b 100644 --- a/src/util.ts +++ b/src/util.ts @@ -33,3 +33,15 @@ export function nextPowerOf2(n: number): number { return i; } + +export class Listenable { + private readonly listeners: Array<(...args: T) => void> = []; + + public addListener(listener: (...args: T) => void): void { + this.listeners.push(listener); + } + + protected runListeners(...args: T): void { + this.listeners.forEach((l) => l(...args)); + } +} diff --git a/src/view/input/DirectionHandler.ts b/src/view/input/DirectionHandler.ts new file mode 100644 index 0000000..691ba01 --- /dev/null +++ b/src/view/input/DirectionHandler.ts @@ -0,0 +1,36 @@ +import {Listenable} from '../../util'; +import InputHandler from './InputHandler'; + +import {vec2} from 'gl-matrix'; + +export const enum Keycode { + Left = 37, + Up = 38, + Right = 39, + Down = 40, +} + +export default class DirectionHandler extends Listenable<[vec2]> { + private readonly input: InputHandler; + + constructor() { + super(); + + this.input = new InputHandler(new Set([Keycode.Left, Keycode.Up, Keycode.Right, Keycode.Down])); + + this.input.addListener(() => { + const dir = vec2.create(); + + if (this.input.has(Keycode.Left)) + vec2.add(dir, dir, [-1, 0]); + if (this.input.has(Keycode.Up)) + vec2.add(dir, dir, [0, -1]); + if (this.input.has(Keycode.Right)) + vec2.add(dir, dir, [1, 0]); + if (this.input.has(Keycode.Down)) + vec2.add(dir, dir, [0, 1]); + + this.runListeners(dir); + }); + } +} diff --git a/src/view/input/InputHandler.ts b/src/view/input/InputHandler.ts new file mode 100644 index 0000000..a6f1293 --- /dev/null +++ b/src/view/input/InputHandler.ts @@ -0,0 +1,39 @@ +import {Listenable} from '../../util'; + +export default class InputHandler extends Listenable<[]> { + private readonly keys: Set = new Set(); + + constructor(relevantKeys: Set) { + super(); + + window.addEventListener('keydown', (ev) => { + if (!relevantKeys.has(ev.keyCode)) + return; + + ev.preventDefault(); + + if (this.keys.has(ev.keyCode)) + return; + + this.keys.add(ev.keyCode); + this.runListeners(); + }); + + window.addEventListener('keyup', (ev) => { + if (!relevantKeys.has(ev.keyCode)) + return; + + ev.preventDefault(); + + if (!this.keys.has(ev.keyCode)) + return; + + this.keys.delete(ev.keyCode); + this.runListeners(); + }); + } + + public has(key: number): boolean { + return this.keys.has(key); + } +} diff --git a/src/view/renderer/Renderer.ts b/src/view/renderer/Renderer.ts index 9358515..a0ecf41 100644 --- a/src/view/renderer/Renderer.ts +++ b/src/view/renderer/Renderer.ts @@ -45,6 +45,10 @@ export default class Renderer { return this.shaders.samplerLoc; } + public setTranslation(v: Float32List) { + this.gl.uniform2fv(this.shaders.translateLoc, v); + } + private mkContext(): WebGLRenderingContext { const gl = ( this.canvas.getContext('webgl') || this.canvas.getContext('experimental-webgl') @@ -66,6 +70,6 @@ export default class Renderer { mat4.scale(this.viewport, this.viewport, [2 * 64 / w, -2 * 64 / h, 1.0]); this.gl.uniformMatrix4fv(this.shaders.viewportLoc, false, this.viewport); - this.gl.uniform2f(this.shaders.translateLoc, -5.0, -5.0); + this.setTranslation([-5, -5]); } } -- cgit v1.2.3