diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2018-10-31 10:52:57 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2018-10-31 10:52:57 +0100 |
commit | 1712352d1c72628a045300fe922c82cd3214070a (patch) | |
tree | 620bd559e2e8fb018d692cf10c20ecd7d108cb04 | |
parent | a86a80e402d5cc58bc2bf248ddbf82d5fafa88a1 (diff) | |
download | rpgedit-1712352d1c72628a045300fe922c82cd3214070a.tar rpgedit-1712352d1c72628a045300fe922c82cd3214070a.zip |
view: add simple input handlers
-rw-r--r-- | src/util.ts | 12 | ||||
-rw-r--r-- | src/view/input/DirectionHandler.ts | 36 | ||||
-rw-r--r-- | src/view/input/InputHandler.ts | 39 | ||||
-rw-r--r-- | src/view/renderer/Renderer.ts | 6 |
4 files changed, 92 insertions, 1 deletions
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<T extends any[]> { + 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<number> = new Set(); + + constructor(relevantKeys: Set<number>) { + 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]); } } |