From 9be9f8e73940f1a38410575557fcd57cc620a8f4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 5 Nov 2018 01:28:35 +0100 Subject: Read collision barriers from map file --- src/controller/gamecontext.ts | 58 ++++++++++++++++++++++--------------------- src/model/data/map.ts | 10 ++++++++ 2 files changed, 40 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/controller/gamecontext.ts b/src/controller/gamecontext.ts index 8107b31..cfdcda5 100644 --- a/src/controller/gamecontext.ts +++ b/src/controller/gamecontext.ts @@ -1,4 +1,4 @@ -import { MapData } from '../model/data/map'; +import { Collision, MapData } from '../model/data/map'; import { loadSimpleEntity } from '../view/entity'; import { DirectionHandler } from '../view/input/directionhandler'; @@ -13,19 +13,41 @@ import { vec2 } from 'gl-matrix'; export class GameContext { public static async load(renderer: Renderer): Promise { - const mapView = this.loadMap(renderer); const entity = loadSimpleEntity(renderer, 'simple_circle'); + const [mapView, collision] = await this.loadMap(renderer); return new GameContext( renderer, - await mapView, + mapView, await entity, + collision, ); } - private static async loadMap(renderer: Renderer): Promise { + private static mkCollision(collision: Collision[]): LineSegment[] { + const ret: LineSegment[] = []; + + for (const c of collision) { + switch (c.type) { + case 'polygon': + if (!c.vertices.length) + continue; + + let prev = c.vertices[c.vertices.length - 1]; + + for (const v of c.vertices) { + ret.push(LineSegment.fromPoints(vec2.clone(prev), vec2.clone(v))); + prev = v; + } + } + } + + return ret; + } + + private static async loadMap(renderer: Renderer): Promise<[SpriteView, LineSegment[]]> { const map = new MapData(await getJSON('resources/map/test.json')); - return loadMap(renderer, map); + return [await loadMap(renderer, map), this.mkCollision(map.collision)]; } private time: number|null = null; @@ -40,32 +62,12 @@ export class GameContext { private readonly entityMovement: vec2 = vec2.create(); private readonly collisionRadius = 7 / 16; - private readonly walls: LineSegment[] = [ - LineSegment.fromPoints(vec2.fromValues(1, 1), vec2.fromValues(11, 1)), - - LineSegment.fromPoints(vec2.fromValues(11, 1), vec2.fromValues(11, 5)), - LineSegment.fromPoints(vec2.fromValues(11, 5), vec2.fromValues(12, 5)), - LineSegment.fromPoints(vec2.fromValues(12, 5), vec2.fromValues(12, 7)), - LineSegment.fromPoints(vec2.fromValues(12, 7), vec2.fromValues(11, 7)), - LineSegment.fromPoints(vec2.fromValues(11, 7), vec2.fromValues(11, 11)), - - LineSegment.fromPoints(vec2.fromValues(11, 11), vec2.fromValues(7, 11)), - LineSegment.fromPoints(vec2.fromValues(7, 11), vec2.fromValues(7, 12)), - LineSegment.fromPoints(vec2.fromValues(7, 12), vec2.fromValues(5, 12)), - LineSegment.fromPoints(vec2.fromValues(5, 12), vec2.fromValues(5, 11)), - LineSegment.fromPoints(vec2.fromValues(5, 11), vec2.fromValues(1, 11)), - - LineSegment.fromPoints(vec2.fromValues(1, 11), vec2.fromValues(1, 7)), - LineSegment.fromPoints(vec2.fromValues(1, 7), vec2.fromValues(0, 7)), - LineSegment.fromPoints(vec2.fromValues(0, 7), vec2.fromValues(0, 5)), - LineSegment.fromPoints(vec2.fromValues(0, 5), vec2.fromValues(1, 5)), - LineSegment.fromPoints(vec2.fromValues(1, 5), vec2.fromValues(1, 1)), - ]; private constructor( private readonly renderer: Renderer, private readonly mapView: SpriteView, private readonly entity: SpriteView, + private readonly collision: LineSegment[], ) { this.input = new DirectionHandler(); this.input.addListener((v) => { @@ -99,8 +101,8 @@ export class GameContext { const move = new Movement(this.entityPos, dest); - for (const w of this.walls) { - if (!w.collidesMoveCircle(dest2, move, this.collisionRadius)) + for (const c of this.collision) { + if (!c.collidesMoveCircle(dest2, move, this.collisionRadius)) continue; if (!vec2.exactEquals(dest, dest2)) { diff --git a/src/model/data/map.ts b/src/model/data/map.ts index d6fd835..4d9ecda 100644 --- a/src/model/data/map.ts +++ b/src/model/data/map.ts @@ -1,11 +1,20 @@ +export interface CollisionPolygon { + readonly type: 'polygon'; + readonly vertices: Array<[number, number]>; +} + +export type Collision = CollisionPolygon; + export interface Input { readonly tiles: string[]; readonly layers: number[][][]; + readonly collision: Collision[]; } export class MapData { public readonly tiles: string[]; public readonly layers: number[][][]; + public readonly collision: Collision[]; public readonly width: number; public readonly height: number; @@ -13,6 +22,7 @@ export class MapData { constructor(data: Input) { this.tiles = data.tiles; this.layers = data.layers; + this.collision = data.collision; this.height = this.layers[0].length; this.width = this.layers[0][0].length; -- cgit v1.2.3