diff options
-rw-r--r-- | src/app.ts | 6 | ||||
-rw-r--r-- | src/control/MapContext.ts | 33 | ||||
-rw-r--r-- | src/model/Direction.ts | 4 | ||||
-rw-r--r-- | src/view/InputHandler.ts | 40 | ||||
-rw-r--r-- | src/view/MapView.ts | 30 |
5 files changed, 94 insertions, 19 deletions
@@ -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)); } } |