Read collision barriers from map file
This commit is contained in:
parent
5593bf2d36
commit
9be9f8e739
4 changed files with 64 additions and 29 deletions
23
dist/resources/map/test.json
vendored
23
dist/resources/map/test.json
vendored
|
@ -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]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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<GameContext> {
|
||||
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<SpriteView> {
|
||||
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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"curly": [true, "as-needed"],
|
||||
"curly": false,
|
||||
"indent": [true, "tabs"],
|
||||
"interface-name": false,
|
||||
"max-classes-per-file": false,
|
||||
|
|
Reference in a new issue