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 --- dist/resources/map/test.json | 23 +++++++++++++++++ src/controller/gamecontext.ts | 58 ++++++++++++++++++++++--------------------- src/model/data/map.ts | 10 ++++++++ tslint.json | 2 +- 4 files changed, 64 insertions(+), 29 deletions(-) diff --git a/dist/resources/map/test.json b/dist/resources/map/test.json index bb0b1da..0fede44 100644 --- a/dist/resources/map/test.json +++ b/dist/resources/map/test.json @@ -46,5 +46,28 @@ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ] + ], + "collision": [ + { + "type": "polygon", + "vertices": [ + [1, 1], + [11, 1], + [11, 5], + [12, 5], + [12, 7], + [11, 7], + [11, 11], + [7, 11], + [7, 12], + [5, 12], + [5, 11], + [1, 11], + [1, 7], + [0, 7], + [0, 5], + [1, 5] + ] + } ] } 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; diff --git a/tslint.json b/tslint.json index c6d9646..3d735e4 100644 --- a/tslint.json +++ b/tslint.json @@ -5,7 +5,7 @@ ], "jsRules": {}, "rules": { - "curly": [true, "as-needed"], + "curly": false, "indent": [true, "tabs"], "interface-name": false, "max-classes-per-file": false, -- cgit v1.2.3