Add support for WASD keyboard controls to the 3D demo

This commit is contained in:
Patrick Walton 2017-09-11 13:23:25 -07:00
parent e13f0f7006
commit 6e4f0b0734
1 changed files with 48 additions and 12 deletions

View File

@ -9,6 +9,8 @@
// except according to those terms.
import * as glmatrix from 'gl-matrix';
import * as _ from 'lodash';
import {PathfinderView} from "./view";
const ORTHOGRAPHIC_ZOOM_SPEED: number = 1.0 / 100.0;
@ -19,10 +21,21 @@ const ZOOM_OUT_FACTOR: number = 1.0 / ZOOM_IN_FACTOR;
const PERSPECTIVE_MOVEMENT_SPEED: number = 10.0;
const PERSPECTIVE_ROTATION_SPEED: number = 1.0 / 300.0;
const PERSPECTIVE_MOVEMENT_VECTORS: PerspectiveMovementVectors = _.fromPairs([
['W'.charCodeAt(0), glmatrix.vec3.fromValues(0, 0, PERSPECTIVE_MOVEMENT_SPEED)],
['A'.charCodeAt(0), glmatrix.vec3.fromValues(PERSPECTIVE_MOVEMENT_SPEED, 0, 0)],
['S'.charCodeAt(0), glmatrix.vec3.fromValues(0, 0, -PERSPECTIVE_MOVEMENT_SPEED)],
['D'.charCodeAt(0), glmatrix.vec3.fromValues(-PERSPECTIVE_MOVEMENT_SPEED, 0, 0)],
]);
const MOVEMENT_INTERVAL_DELAY: number = 10;
const INITIAL_TRANSLATION: glmatrix.vec3 = glmatrix.vec3.fromValues(0.0, 0.0, -1000.0);
interface PerspectiveMovementVectors {
[keyCode: number]: glmatrix.vec3;
}
export abstract class Camera {
constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas;
@ -137,6 +150,9 @@ export class PerspectiveCamera extends Camera {
this.canvas.addEventListener('mouseup', event => this.onMouseUp(event), false);
this.canvas.addEventListener('mousemove', event => this.onMouseMove(event), false);
window.addEventListener('keydown', event => this.onKeyDown(event), false);
window.addEventListener('keyup', event => this.onKeyUp(event), false);
this.onChange = null;
}
@ -150,11 +166,42 @@ export class PerspectiveCamera extends Camera {
if (event.button !== 1)
this.movementDelta[0] = -this.movementDelta[0];
this.startMoving();
}
private onMouseUp(event: MouseEvent): void {
this.stopMoving();
}
private onMouseMove(event: MouseEvent): void {
if (document.pointerLockElement !== this.canvas)
return;
this.rotation[0] += event.movementX * PERSPECTIVE_ROTATION_SPEED;
this.rotation[1] += event.movementY * PERSPECTIVE_ROTATION_SPEED;
if (this.onChange != null)
this.onChange();
}
private onKeyDown(event: KeyboardEvent): void {
if (PERSPECTIVE_MOVEMENT_VECTORS.hasOwnProperty(event.keyCode)) {
this.movementDelta = glmatrix.vec3.clone(PERSPECTIVE_MOVEMENT_VECTORS[event.keyCode]);
this.startMoving();
}
}
private onKeyUp(event: KeyboardEvent): void {
if (PERSPECTIVE_MOVEMENT_VECTORS.hasOwnProperty(event.keyCode))
this.stopMoving();
}
private startMoving(): void {
if (this.movementInterval == null)
this.movementInterval = window.setInterval(() => this.move(), MOVEMENT_INTERVAL_DELAY);
}
private onMouseUp(event: MouseEvent): void {
private stopMoving(): void {
if (this.movementInterval != null) {
window.clearInterval(this.movementInterval);
this.movementInterval = null;
@ -174,17 +221,6 @@ export class PerspectiveCamera extends Camera {
this.onChange();
}
private onMouseMove(event: MouseEvent): void {
if (document.pointerLockElement !== this.canvas)
return;
this.rotation[0] += event.movementX * PERSPECTIVE_ROTATION_SPEED;
this.rotation[1] += event.movementY * PERSPECTIVE_ROTATION_SPEED;
if (this.onChange != null)
this.onChange();
}
get rotationMatrix(): glmatrix.mat4 {
const matrix = glmatrix.mat4.create();
glmatrix.mat4.fromXRotation(matrix, this.rotation[1]);