summaryrefslogtreecommitdiffstats
path: root/src/controller/gamecontext.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/controller/gamecontext.ts')
-rw-r--r--src/controller/gamecontext.ts54
1 files changed, 42 insertions, 12 deletions
diff --git a/src/controller/gamecontext.ts b/src/controller/gamecontext.ts
index 8ec54b5..a12e3bc 100644
--- a/src/controller/gamecontext.ts
+++ b/src/controller/gamecontext.ts
@@ -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;
}