Allow interacting with entities

This commit is contained in:
Matthias Schiffer 2018-11-09 13:27:49 +01:00
parent e0eddb8741
commit 453a9391cc
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
6 changed files with 140 additions and 62 deletions

View file

@ -3,7 +3,7 @@ import { EntityContext } from './entitycontext';
import { MapData } from '../model/data/map';
import { DirectionHandler } from '../view/input/directionhandler';
import { ButtonCode, GameInputHandler } from '../view/input/gameinput';
import { loadMap } from '../view/map';
import { Renderer } from '../view/renderer/renderer';
import { SpriteView } from '../view/sprite';
@ -44,14 +44,16 @@ export class GameContext implements CollidableGroup {
private time: number|null = null;
private readonly tick = 10; // ms per tick
private readonly speed = 0.04; // movement per tick
private readonly maxSpeed = 0.04; // movement per tick
private readonly maxSkip = 20; // maximum ticks to process in a single render step
private readonly input: DirectionHandler;
private readonly input: GameInputHandler;
private readonly playerMovement: vec2 = vec2.create();
private readonly playerDir: vec2 = vec2.fromValues(0, 1);
private speed: number = 0;
private readonly collisionRadius = 7 / 16;
private readonly interactLength = 1 / 32;
private constructor(
private readonly renderer: Renderer,
@ -60,12 +62,23 @@ export class GameContext implements CollidableGroup {
private readonly entities: EntityContext[],
private readonly collision: Collidable[],
) {
this.input = new DirectionHandler();
this.input.addListener((v) => {
if (vec2.sqrLen(v) > 0)
vec2.normalize(this.playerMovement, v);
else
vec2.copy(this.playerMovement, [0, 0]);
this.input = new GameInputHandler();
this.input.addListener((input) => {
switch (input.type) {
case 'button':
if (input.button === ButtonCode.Action)
this.interact();
break;
case 'direction':
if (vec2.sqrLen(input.direction) > 0) {
vec2.copy(this.playerDir, input.direction);
this.speed = this.maxSpeed;
} else {
this.speed = 0;
}
break;
}
});
window.requestAnimationFrame(this.render);
@ -86,6 +99,23 @@ export class GameContext implements CollidableGroup {
return diff;
}
private canInteract(c: CollidableGroup): boolean {
const dest = vec2.scaleAndAdd(vec2.create(), this.player.pos, this.playerDir, this.interactLength);
const move = new Movement(this.player.pos, dest);
return collide(c, vec2.create(), move, this.collisionRadius);
}
private interact(): void {
for (const e of this.entities) {
if (!this.canInteract(e))
continue;
e.interact();
break;
}
}
private updateStepCollide(out: vec2, dest: vec2): boolean {
const move = new Movement(this.player.pos, dest);
@ -102,7 +132,7 @@ export class GameContext implements CollidableGroup {
}
private updateStep(): void {
const dest = vec2.scaleAndAdd(vec2.create(), this.player.pos, this.playerMovement, this.speed);
const dest = vec2.scaleAndAdd(vec2.create(), this.player.pos, this.playerDir, this.speed);
const newDest = vec2.create();
while (this.updateStepCollide(newDest, dest)) {
@ -118,7 +148,7 @@ export class GameContext implements CollidableGroup {
private update(time: number): void {
const diff = Math.min(this.maxSkip, this.updateTime(time));
if (vec2.sqrLen(this.playerMovement) === 0) {
if (!this.speed) {
this.renderer.snapToGrid(this.player.pos, this.player.pos);
return;
}