Allow interacting with entities
This commit is contained in:
parent
e0eddb8741
commit
453a9391cc
6 changed files with 140 additions and 62 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Reference in a new issue