'use strict'; import Direction from '../model/Direction'; import Entity from '../model/Entity'; import EntityPosition from '../model/EntityPosition'; import MapData from '../model/MapData'; import Position from '../model/Position'; import Transition from '../model/Transition'; import InputHandler from '../view/InputHandler'; import MapView from '../view/MapView'; export default class MapContext { view: MapView; entities: EntityPosition[] = []; playerEntity: EntityPosition; collision: number[][]; constructor(private map: MapData, private inputHandler: InputHandler) { this.collision = new Array(map.width); for (let i = 0; i < map.width; i++) { this.collision[i] = new Array(map.height); for (let j = 0; j < map.height; j++) this.collision[i][j] = map.collision[j][i] == '0' ? 0 : 1; } this.playerEntity = new EntityPosition( new Entity('square'), new Position(8, 8), Direction.East ); this.addEntity(this.playerEntity); this.addEntity(new EntityPosition( new Entity('square'), new Position(10, 10), Direction.East )); this.view = new MapView( map, this.entities, this.playerEntity, (time: number) => this.updateState(time) ); inputHandler.addListener(() => { if (this.updateState(performance.now())) this.view.redraw(); }); } private inMap(p: Position): boolean { return p.x >= 0 && p.x < this.map.width && p.y >= 0 && p.y < this.map.height; } private incCollision(p: Position) { if (this.inMap(p)) this.collision[p.x][p.y]++; } private decCollision(p: Position) { if (this.inMap(p)) this.collision[p.x][p.y]--; } private collides(p: Position): boolean { return (!this.inMap(p)) || (this.collision[p.x][p.y] > 0); } private addEntity(entity: EntityPosition) { this.entities.push(entity); this.incCollision(entity.position); } private addTransition(entity: EntityPosition, dest: Position, start: number, dur: number) { entity.transition = new Transition(start, start+dur, entity.position, dest); this.incCollision(dest); } private finishTransition(entity: EntityPosition) { this.decCollision(entity.position); entity.position = entity.transition.dest; entity.transition = null; } private updateState(time: number): boolean { var ret = false; while (true) { let origTime = time; if (this.playerEntity.transition && this.playerEntity.transition.end <= time) { origTime = this.playerEntity.transition.end; this.finishTransition(this.playerEntity); ret = true; } if (this.playerEntity.transition) return true; let dir: Direction = null; 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 (dir === null) return ret; this.playerEntity.direction = dir; ret = true; let dest = this.playerEntity.position.translate(dir, 1); if (this.collides(dest)) return true; this.addTransition(this.playerEntity, dest, origTime, 250); } } }