view: add simple input handlers
This commit is contained in:
parent
a86a80e402
commit
1712352d1c
4 changed files with 92 additions and 1 deletions
12
src/util.ts
12
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));
|
||||
}
|
||||
}
|
||||
|
|
36
src/view/input/DirectionHandler.ts
Normal file
36
src/view/input/DirectionHandler.ts
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
39
src/view/input/InputHandler.ts
Normal file
39
src/view/input/InputHandler.ts
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue