view: add simple input handlers

This commit is contained in:
Matthias Schiffer 2018-10-31 10:52:57 +01:00
parent a86a80e402
commit 1712352d1c
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
4 changed files with 92 additions and 1 deletions

View file

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

View file

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

View file

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

View file

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