import MapData from '../model/data/MapData'; import { loadSimpleEntity } from '../view/entity'; import DirectionHandler from '../view/input/DirectionHandler'; import { loadMap } from '../view/map'; import Renderer from '../view/renderer/Renderer'; import { SpriteView } from '../view/sprite'; import { getJSON } from '../util'; import { vec2 } from 'gl-matrix'; function snapToGrid(out: vec2, a: vec2): void { const res = 64; vec2.scale(out, a, res); vec2.round(out, out); vec2.scale(out, out, 1 / res); } export class GameContext { public static async load(renderer: Renderer): Promise { const [ mapView, entity, ] = await Promise.all([ GameContext.loadMap(renderer), loadSimpleEntity(renderer, 'simple_square'), ]); return new GameContext( renderer, mapView, entity, ); } private static async loadMap(renderer: Renderer): Promise { const map = new MapData(await getJSON('resources/map/test.json')); return loadMap(renderer, map); } private time: number|null = null; private readonly speed = 1 / 100; private readonly input: DirectionHandler; private readonly entityPos: vec2 = vec2.create(); private readonly entityMovement: vec2 = vec2.create(); private constructor( private readonly renderer: Renderer, private readonly mapView: SpriteView, private readonly entity: SpriteView, ) { this.input = new DirectionHandler(); this.input.addListener((v) => { if (vec2.sqrLen(v) > 0) vec2.normalize(this.entityMovement, v); else vec2.copy(this.entityMovement, [0, 0]); }); window.requestAnimationFrame(this.render); } private updateTime(time: number): number { let diff = 0; if (this.time !== null) diff = time - this.time; this.time = time; return diff; } private update(time: number): void { const diff = this.updateTime(time); vec2.scaleAndAdd(this.entityPos, this.entityPos, this.entityMovement, diff * this.speed); snapToGrid(this.entityPos, this.entityPos); } private render = (time: number) => { this.update(time); this.renderer.setCenter(this.entityPos); this.renderer.clear(); this.mapView.render(); this.renderer.setTranslation(this.entityPos); this.entity.render(); window.requestAnimationFrame(this.render); } }