Pathfinding and walking the path
This commit is contained in:
59
js/grid.js
59
js/grid.js
@@ -5,16 +5,18 @@ export class Grid {
|
|||||||
this.layers = new Map();
|
this.layers = new Map();
|
||||||
this.masks = new Map();
|
this.masks = new Map();
|
||||||
this.prnt = prnt;
|
this.prnt = prnt;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
this.prnt.style.display = 'grid';
|
this.prnt.style.display = 'grid';
|
||||||
this.prnt.style.gridTemplateColumns = `repeat(${width}, 1fr)`;
|
this.prnt.style.gridTemplateColumns = `repeat(${this.width}, 1fr)`;
|
||||||
this.prnt.style.gridTemplateRows = `repeat(${height}, 1fr)`;
|
this.prnt.style.gridTemplateRows = `repeat(${this.height}, 1fr)`;
|
||||||
this.prnt.style.backgroundImage = `url("images/${tileset}/land.svg")`;
|
this.prnt.style.backgroundImage = `url("images/${tileset}/land.svg")`;
|
||||||
for (let i = 0; i <= layers.length; i++) {
|
for (let i = 0; i <= layers.length; i++) {
|
||||||
const name = layers[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) {
|
for (const name of masks) {
|
||||||
this.masks.set(name, new Mask(width, height));
|
this.masks.set(name, new Mask(this.width, this.height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add_tile(tile_factory, x, y) {
|
add_tile(tile_factory, x, y) {
|
||||||
@@ -28,5 +30,54 @@ export class Grid {
|
|||||||
}
|
}
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
add_debug_tile(x, y, color) {
|
||||||
|
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, src, dst) {
|
||||||
|
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 = [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[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 = [];
|
||||||
|
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 [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//# sourceMappingURL=grid.js.map
|
//# sourceMappingURL=grid.js.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"grid.js","sourceRoot":"","sources":["../ts/grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,MAAM,OAAO,IAAI;IAKf,YAAY,IAAiB,EAAE,KAAa,EAAE,MAAc,EAAE,OAAe,EAAE,MAAgB,EAAE,KAAe;QAHhH,WAAM,GAAuB,IAAI,GAAG,EAAiB,CAAC;QACtD,UAAK,GAAsB,IAAI,GAAG,EAAgB,CAAC;QAGjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,UAAU,KAAK,QAAQ,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,UAAU,MAAM,QAAQ,CAAC;QAC5D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,eAAe,OAAO,aAAa,CAAC;QAEtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACvC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;SACvD;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;SAC/C;IACH,CAAC;IAED,QAAQ,CAAC,YAAyB,EAAE,CAAS,EAAE,CAAS;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QAEjF,sBAAsB;QACtB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEjC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE;YACrC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;SAC1C;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
{"version":3,"file":"grid.js","sourceRoot":"","sources":["../ts/grid.ts"],"names":[],"mappings":"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"}
|
||||||
47
js/tower.js
47
js/tower.js
@@ -71,30 +71,6 @@ export function main() {
|
|||||||
grid.add_tile(tiles.BRIDGE_LR, 92, 52);
|
grid.add_tile(tiles.BRIDGE_LR, 92, 52);
|
||||||
grid.add_tile(tiles.BRIDGE_LR, 92, 36);
|
grid.add_tile(tiles.BRIDGE_LR, 92, 36);
|
||||||
grid.add_tile(tiles.BRIDGE_LR, 92, 20);
|
grid.add_tile(tiles.BRIDGE_LR, 92, 20);
|
||||||
function add_debug_tile(x, y, color) {
|
|
||||||
const div = document.createElement('div');
|
|
||||||
real.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';
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const m = grid.masks.get('walkable').mask;
|
|
||||||
for (let x = 0; x < m.length; x++) {
|
|
||||||
for (let y = 0; y < m[x].length; y++) {
|
|
||||||
if (m[x][y]) {
|
|
||||||
add_debug_tile(x, y, 'orange');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
add_debug_tile(118, 23, 'blue');
|
|
||||||
add_debug_tile(44, 94, 'red');
|
|
||||||
function rand(min, max) {
|
function rand(min, max) {
|
||||||
return Math.round(Math.random() * (max - min) + min);
|
return Math.round(Math.random() * (max - min) + min);
|
||||||
}
|
}
|
||||||
@@ -109,15 +85,30 @@ export function main() {
|
|||||||
grid.add_tile(tiles.FIREBALL_IMPACT, 62 + target_relative_x, 54 + target_relative_y);
|
grid.add_tile(tiles.FIREBALL_IMPACT, 62 + target_relative_x, 54 + target_relative_y);
|
||||||
}, factory.duration);
|
}, factory.duration);
|
||||||
}, 3250);
|
}, 3250);
|
||||||
const greenaxe = grid.add_tile(tiles.GREENAXE, 60, 32);
|
const path = grid.get_path('walkable', [118, 23], [44, 94]);
|
||||||
|
const greenaxe = grid.add_tile(tiles.GREENAXE, 115, 18);
|
||||||
greenaxe.play('walk');
|
greenaxe.play('walk');
|
||||||
greenaxe.elem.style.transitionProperty = 'top,left';
|
greenaxe.elem.style.transitionProperty = 'top,left';
|
||||||
greenaxe.elem.style.transitionDuration = '25s';
|
greenaxe.elem.style.transitionDuration = '0.5s';
|
||||||
greenaxe.elem.style.transitionTimingFunction = 'linear';
|
greenaxe.elem.style.transitionTimingFunction = 'linear';
|
||||||
greenaxe.elem.style.top = '0';
|
greenaxe.elem.style.top = '0';
|
||||||
greenaxe.elem.style.left = '0';
|
greenaxe.elem.style.left = '0';
|
||||||
greenaxe.elem.style.transform = 'scaleX(-1)';
|
let prev = [118, 23];
|
||||||
setTimeout(() => greenaxe.elem.style.left = '-500%', 100);
|
setInterval(() => {
|
||||||
|
const next = path.shift();
|
||||||
|
if (!next) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (next[0] - prev[0] < 0) {
|
||||||
|
greenaxe.elem.style.transform = 'scaleX(-1)';
|
||||||
|
}
|
||||||
|
else if (next[0] - prev[0] > 0) {
|
||||||
|
greenaxe.elem.style.transform = 'scaleX(1)';
|
||||||
|
}
|
||||||
|
prev = next;
|
||||||
|
greenaxe.elem.style.left = `${(next[0] - 118) / 6 * 100}%`;
|
||||||
|
greenaxe.elem.style.top = `${(next[1] - 23) / 6 * 100}%`;
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
main();
|
main();
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
72
ts/grid.ts
72
ts/grid.ts
@@ -3,26 +3,32 @@ import { Mask } from './mask.js';
|
|||||||
import { Tile } from './tile.js';
|
import { Tile } from './tile.js';
|
||||||
import { TileFactory } from './tile_factory.js';
|
import { TileFactory } from './tile_factory.js';
|
||||||
|
|
||||||
|
type Point = [number, number]
|
||||||
|
|
||||||
export class Grid {
|
export class Grid {
|
||||||
prnt: HTMLElement;
|
prnt: HTMLElement;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
layers: Map<string, Layer> = new Map<string, Layer>();
|
layers: Map<string, Layer> = new Map<string, Layer>();
|
||||||
masks: Map<string, Mask> = new Map<string, Mask>();
|
masks: Map<string, Mask> = new Map<string, Mask>();
|
||||||
|
|
||||||
constructor(prnt: HTMLElement, width: number, height: number, tileset: string, layers: string[], masks: string[]) {
|
constructor(prnt: HTMLElement, width: number, height: number, tileset: string, layers: string[], masks: string[]) {
|
||||||
this.prnt = prnt;
|
this.prnt = prnt;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
|
||||||
this.prnt.style.display = 'grid';
|
this.prnt.style.display = 'grid';
|
||||||
this.prnt.style.gridTemplateColumns = `repeat(${width}, 1fr)`;
|
this.prnt.style.gridTemplateColumns = `repeat(${this.width}, 1fr)`;
|
||||||
this.prnt.style.gridTemplateRows = `repeat(${height}, 1fr)`;
|
this.prnt.style.gridTemplateRows = `repeat(${this.height}, 1fr)`;
|
||||||
this.prnt.style.backgroundImage = `url("images/${tileset}/land.svg")`;
|
this.prnt.style.backgroundImage = `url("images/${tileset}/land.svg")`;
|
||||||
|
|
||||||
for (let i = 0; i <= layers.length; i++) {
|
for (let i = 0; i <= layers.length; i++) {
|
||||||
const name = layers[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) {
|
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;
|
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 [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
51
ts/tower.ts
51
ts/tower.ts
@@ -85,33 +85,6 @@ export function main() {
|
|||||||
grid.add_tile(tiles.BRIDGE_LR, 92, 36);
|
grid.add_tile(tiles.BRIDGE_LR, 92, 36);
|
||||||
grid.add_tile(tiles.BRIDGE_LR, 92, 20);
|
grid.add_tile(tiles.BRIDGE_LR, 92, 20);
|
||||||
|
|
||||||
function add_debug_tile(x: number, y: number, color: string) {
|
|
||||||
const div = document.createElement('div');
|
|
||||||
real.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';
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const m = grid.masks.get('walkable')!.mask;
|
|
||||||
for (let x = 0; x < m.length; x++) {
|
|
||||||
for (let y = 0; y < m[x].length; y++) {
|
|
||||||
if (m[x][y]) {
|
|
||||||
add_debug_tile(x, y, 'orange');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add_debug_tile(118, 23, 'blue');
|
|
||||||
add_debug_tile(44, 94, 'red');
|
|
||||||
|
|
||||||
function rand(min: number, max: number): number {
|
function rand(min: number, max: number): number {
|
||||||
return Math.round(Math.random() * (max - min) + min);
|
return Math.round(Math.random() * (max - min) + min);
|
||||||
}
|
}
|
||||||
@@ -128,15 +101,31 @@ export function main() {
|
|||||||
}, factory.duration);
|
}, factory.duration);
|
||||||
}, 3250);
|
}, 3250);
|
||||||
|
|
||||||
const greenaxe = grid.add_tile(tiles.GREENAXE, 60, 32);
|
const path = grid.get_path('walkable', [118, 23], [44, 94]);
|
||||||
|
|
||||||
|
const greenaxe = grid.add_tile(tiles.GREENAXE, 115, 18);
|
||||||
greenaxe.play('walk');
|
greenaxe.play('walk');
|
||||||
greenaxe.elem.style.transitionProperty = 'top,left';
|
greenaxe.elem.style.transitionProperty = 'top,left';
|
||||||
greenaxe.elem.style.transitionDuration = '25s';
|
greenaxe.elem.style.transitionDuration = '0.5s';
|
||||||
greenaxe.elem.style.transitionTimingFunction = 'linear';
|
greenaxe.elem.style.transitionTimingFunction = 'linear';
|
||||||
greenaxe.elem.style.top = '0';
|
greenaxe.elem.style.top = '0';
|
||||||
greenaxe.elem.style.left = '0';
|
greenaxe.elem.style.left = '0';
|
||||||
greenaxe.elem.style.transform = 'scaleX(-1)';
|
|
||||||
setTimeout(() => greenaxe.elem.style.left = '-500%', 100);
|
let prev = [118, 23];
|
||||||
|
setInterval(() => {
|
||||||
|
const next = path.shift();
|
||||||
|
if (!next) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (next[0] - prev[0] < 0) {
|
||||||
|
greenaxe.elem.style.transform = 'scaleX(-1)';
|
||||||
|
} else if (next[0] - prev[0] > 0) {
|
||||||
|
greenaxe.elem.style.transform = 'scaleX(1)';
|
||||||
|
}
|
||||||
|
prev = next;
|
||||||
|
greenaxe.elem.style.left = `${(next[0] - 118) / 6 * 100}%`;
|
||||||
|
greenaxe.elem.style.top = `${(next[1] - 23) / 6 * 100}%`;
|
||||||
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|||||||
Reference in New Issue
Block a user