summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/app.ts6
-rw-r--r--src/control/MapContext.ts33
-rw-r--r--src/model/Direction.ts4
-rw-r--r--src/view/InputHandler.ts40
-rw-r--r--src/view/MapView.ts30
5 files changed, 94 insertions, 19 deletions
diff --git a/src/app.ts b/src/app.ts
index d1ca3cd..e47d41f 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -9,6 +9,7 @@ _ = lodash;
import MapContext from './control/MapContext';
import MapData from './model/MapData';
+import InputHandler from './view/InputHandler';
var mapContext: MapContext;
@@ -17,8 +18,9 @@ window.onload = () => {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
- let mapDef = new MapData(JSON.parse(this.responseText));
- mapContext = new MapContext(mapDef);
+ var mapDef = new MapData(JSON.parse(this.responseText));
+ var inputHandler = new InputHandler();
+ mapContext = new MapContext(mapDef, inputHandler);
}
xhr.open('GET', 'resources/map/test.json', true);
diff --git a/src/control/MapContext.ts b/src/control/MapContext.ts
index 4bc75c7..df7eff6 100644
--- a/src/control/MapContext.ts
+++ b/src/control/MapContext.ts
@@ -7,6 +7,7 @@ import EntityPosition from '../model/EntityPosition';
import MapData from '../model/MapData';
import Position from '../model/Position';
+import InputHandler from '../view/InputHandler';
import MapView from '../view/MapView';
@@ -16,7 +17,7 @@ export default class MapContext {
entities: {[key: string]: EntityPosition} = {};
playerEntity: EntityPosition;
- constructor(public map: MapData) {
+ constructor(private map: MapData, private inputHandler: InputHandler) {
this.playerEntity = new EntityPosition(
new Entity('square'),
new Position(8, 8),
@@ -25,10 +26,36 @@ export default class MapContext {
this.addEntity(this.playerEntity);
- this.view = new MapView(map, this.entities);
+ this.view = new MapView(map, this.entities, (time: number) => this.updateState(time));
+
+ inputHandler.addListener(() => {
+ if (this.updateState(performance.now()))
+ this.view.redraw();
+ });
}
- addEntity(entity: EntityPosition) {
+ private addEntity(entity: EntityPosition) {
this.entities[entity.position.asString()] = entity;
}
+
+ private updateState(time: number): boolean {
+ var ret = false;
+ var dir = this.playerEntity.direction;
+
+ if (this.inputHandler.keys[InputHandler.Up])
+ dir = Direction.North;
+ else if (this.inputHandler.keys[InputHandler.Right])
+ dir = Direction.East;
+ else if (this.inputHandler.keys[InputHandler.Down])
+ dir = Direction.South;
+ else if (this.inputHandler.keys[InputHandler.Left])
+ dir = Direction.West;
+
+ if (this.playerEntity.direction !== dir) {
+ this.playerEntity.direction = dir;
+ ret = true;
+ }
+
+ return ret;
+ }
}
diff --git a/src/model/Direction.ts b/src/model/Direction.ts
index a0cf45d..7f92588 100644
--- a/src/model/Direction.ts
+++ b/src/model/Direction.ts
@@ -8,6 +8,8 @@ export enum Direction {
West
};
-export function reverse(r: Direction): Direction { return (r+2) % 4; }
+export module Direction {
+ export function reverse(r: Direction): Direction { return (r+2) % 4; }
+}
export default Direction;
diff --git a/src/view/InputHandler.ts b/src/view/InputHandler.ts
new file mode 100644
index 0000000..e39ffe0
--- /dev/null
+++ b/src/view/InputHandler.ts
@@ -0,0 +1,40 @@
+'use strict';
+
+
+import Direction from '../model/Direction';
+
+
+class InputHandler {
+ keys: {[key: number]: boolean} = {};
+
+ listeners: (() => void)[] = [];
+
+ private callListeners() {
+ this.listeners.forEach(l => l());
+ }
+
+ constructor() {
+ window.addEventListener('keydown', (ev) => {
+ this.keys[ev.keyCode] = true;
+ this.callListeners();
+ });
+
+ window.addEventListener('keyup', (ev) => {
+ delete this.keys[ev.keyCode];
+ this.callListeners();
+ });
+ }
+
+ addListener(l: () => void) {
+ this.listeners.push(l);
+ }
+}
+
+module InputHandler {
+ export const Left = 37;
+ export const Up = 38;
+ export const Right = 39;
+ export const Down = 40;
+};
+
+export default InputHandler;
diff --git a/src/view/MapView.ts b/src/view/MapView.ts
index b366d28..1eadebb 100644
--- a/src/view/MapView.ts
+++ b/src/view/MapView.ts
@@ -40,15 +40,17 @@ function loadEntities(entities: EntityPosition[]): Promise<{[key: string]: HTMLI
export default class MapView {
- redrawPending: boolean = false;
+ private redrawPending: boolean = false;
- canvas: HTMLCanvasElement;
- ctx: CanvasRenderingContext2D;
+ private canvas: HTMLCanvasElement;
+ private ctx: CanvasRenderingContext2D;
- tiles: {[key: string]: HTMLImageElement};
- entitySprites: {[key: string]: HTMLImageElement};
+ private tiles: {[key: string]: HTMLImageElement};
+ private entitySprites: {[key: string]: HTMLImageElement};
- constructor(private map: MapData, private entities: {[key: string]: EntityPosition}) {
+ constructor(private map: MapData,
+ private entities: {[key: string]: EntityPosition},
+ private updateState: (time: number) => void) {
this.canvas = document.createElement('canvas');
this.canvas.style.position = 'absolute';
body.appendChild(this.canvas);
@@ -71,11 +73,11 @@ export default class MapView {
});
}
- getEntities(): EntityPosition[] {
- return _.valuesIn<EntityPosition>(this.entities);
+ private getEntities(): EntityPosition[] {
+ return _.values<EntityPosition>(this.entities);
}
- setSize() {
+ private setSize() {
var e = document.documentElement;
this.canvas.width = window.innerWidth || e.clientWidth || body.clientWidth;
this.canvas.height = window.innerHeight || e.clientHeight || body.clientHeight;
@@ -83,14 +85,14 @@ export default class MapView {
this.redraw()
}
- drawTile(x: number, y: number, tile: HTMLImageElement) {
+ private drawTile(x: number, y: number, tile: HTMLImageElement) {
if (!tile)
return;
this.ctx.drawImage(tile, x, y);
}
- drawEntity(e: EntityPosition) {
+ private drawEntity(e: EntityPosition) {
var sprite = this.entitySprites[e.entity.name];
if (!sprite)
return;
@@ -104,7 +106,9 @@ export default class MapView {
);
}
- draw() {
+ private draw(time: number) {
+ this.updateState(time);
+
this.redrawPending = false;
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
@@ -137,6 +141,6 @@ export default class MapView {
return;
this.redrawPending = true;
- window.requestAnimationFrame(() => this.draw());
+ window.requestAnimationFrame((time: number) => this.draw(time));
}
}