Pathfinding and walking the path
This commit is contained in:
72
ts/grid.ts
72
ts/grid.ts
@@ -3,26 +3,32 @@ import { Mask } from './mask.js';
|
||||
import { Tile } from './tile.js';
|
||||
import { TileFactory } from './tile_factory.js';
|
||||
|
||||
type Point = [number, number]
|
||||
|
||||
export class Grid {
|
||||
prnt: HTMLElement;
|
||||
width: number;
|
||||
height: number;
|
||||
layers: Map<string, Layer> = new Map<string, Layer>();
|
||||
masks: Map<string, Mask> = new Map<string, Mask>();
|
||||
|
||||
constructor(prnt: HTMLElement, width: number, height: number, tileset: string, layers: string[], masks: string[]) {
|
||||
this.prnt = prnt;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.prnt.style.display = 'grid';
|
||||
this.prnt.style.gridTemplateColumns = `repeat(${width}, 1fr)`;
|
||||
this.prnt.style.gridTemplateRows = `repeat(${height}, 1fr)`;
|
||||
this.prnt.style.gridTemplateColumns = `repeat(${this.width}, 1fr)`;
|
||||
this.prnt.style.gridTemplateRows = `repeat(${this.height}, 1fr)`;
|
||||
this.prnt.style.backgroundImage = `url("images/${tileset}/land.svg")`;
|
||||
|
||||
for (let i = 0; i <= layers.length; i++) {
|
||||
const name = layers[i];
|
||||
this.layers.set(name, new Layer(i * height, tileset));
|
||||
this.layers.set(name, new Layer(i * this.height, tileset));
|
||||
}
|
||||
|
||||
for (const name of masks) {
|
||||
this.masks.set(name, new Mask(width, height));
|
||||
this.masks.set(name, new Mask(this.width, this.height));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,4 +46,62 @@ export class Grid {
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
add_debug_tile(x: number, y: number, color: string) {
|
||||
const div = document.createElement('div');
|
||||
this.prnt.appendChild(div);
|
||||
div.style.gridColumnStart = `${x + 1}`;
|
||||
div.style.gridRowStart = `${y + 1}`;
|
||||
div.style.gridColumnEnd = 'span 1';
|
||||
div.style.gridRowEnd = 'span 1';
|
||||
div.style.backgroundColor = color;
|
||||
div.style.opacity = '0.3';
|
||||
div.style.zIndex = '1000000';
|
||||
}
|
||||
|
||||
get_path(mask_name: string, src: Point, dst: Point): Point[] {
|
||||
const mask = this.masks.get(mask_name)!;
|
||||
|
||||
const next = [];
|
||||
for (let x = 0; x < this.width; x++) {
|
||||
next.push(Array(this.height).fill(undefined));
|
||||
}
|
||||
|
||||
// BFS
|
||||
const queue: Point[] = [dst];
|
||||
while (queue.length) {
|
||||
const point = queue.shift()!;
|
||||
|
||||
// Horizontal / vertical has to come before diagonal
|
||||
for (const [dx, dy] of [[-1,0], [1,0], [0,-1], [0,1], [-1,-1], [-1,1], [1,-1], [1,1]]) {
|
||||
const check: Point = [point[0] + dx, point[1] + dy];
|
||||
|
||||
if (next[check[0]][check[1]]) {
|
||||
// Already visited
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mask.mask[check[0]][check[1]]) {
|
||||
// Not allowed
|
||||
continue;
|
||||
}
|
||||
|
||||
next[check[0]][check[1]] = point;
|
||||
if (check[0] == src[0] && check[1] == src[1]) {
|
||||
const path: Point[] = [];
|
||||
let cur = src;
|
||||
while (cur[0] != dst[0] || cur[1] != dst[1]) {
|
||||
path.push(cur);
|
||||
cur = next[cur[0]][cur[1]];
|
||||
}
|
||||
path.push(dst);
|
||||
return path;
|
||||
}
|
||||
queue.push(check);
|
||||
}
|
||||
}
|
||||
|
||||
// No valid path
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user