fixed PathFinder and now it is async
This commit is contained in:
parent
fdfa7bd7cb
commit
815422f8e4
@ -1,8 +1,9 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" style="width: 100%; height: 100%;">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<!-- <meta name="viewport" content="width=device-width,initial-scale=1" /> -->
|
||||||
|
|
||||||
<title>Amogus factory</title>
|
<title>Amogus factory</title>
|
||||||
|
|
||||||
@ -14,8 +15,9 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet" />
|
||||||
|
|
||||||
|
|
||||||
<script defer src="/build/bundle.js"></script>
|
<script defer src="/build/bundle.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body></body>
|
<body style="width: 100%; height: 100%;"></body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -74,9 +74,6 @@
|
|||||||
ambientSound = s.ambient;
|
ambientSound = s.ambient;
|
||||||
musicSound = s.music;
|
musicSound = s.music;
|
||||||
});
|
});
|
||||||
|
|
||||||
import {search} from "./Test";
|
|
||||||
search();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="game-ui" class="absolute inset-0 flex items-center justify-center text-white select-none tracking-widest font-pixel pointer-events-none">
|
<div id="game-ui" class="absolute inset-0 flex items-center justify-center text-white select-none tracking-widest font-pixel pointer-events-none">
|
||||||
|
@ -20,6 +20,7 @@ import { WorldChunksVisibilityUpdater } from "./WorldGeneration/WorldChunksVisib
|
|||||||
import { NPCProto } from "./NPC/NPCProto/NPCProto";
|
import { NPCProto } from "./NPC/NPCProto/NPCProto";
|
||||||
import { NPCController } from "./NPC/NPCController/NPCController";
|
import { NPCController } from "./NPC/NPCController/NPCController";
|
||||||
import { PathFinder } from "./Utils/PathFinding.utils";
|
import { PathFinder } from "./Utils/PathFinding.utils";
|
||||||
|
import { getNavigationGridTile } from "./World/NavigationGrid/NavigationGrid";
|
||||||
|
|
||||||
export function generateWorld() {
|
export function generateWorld() {
|
||||||
|
|
||||||
@ -63,10 +64,11 @@ function setupInGameSelector() {
|
|||||||
BC_VIEWPORT.onpointerdown = (e) =>
|
BC_VIEWPORT.onpointerdown = (e) =>
|
||||||
{
|
{
|
||||||
let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y);
|
let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y);
|
||||||
|
// console.log(getNavigationGridTile(t.x, t.y));
|
||||||
// npccc.moveTo(new Point2D(getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN).worldPosition.getX(), getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN).worldPosition.getY()));
|
// npccc.moveTo(new Point2D(getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN).worldPosition.getX(), getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN).worldPosition.getY()));
|
||||||
let tile = getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN);
|
let tile = getNavigationGridTile(t.x, t.y);
|
||||||
if(tile.props.navigationCost > 100) return;
|
if(tile.isObstacle) return;
|
||||||
npccc.moveTo(new PointInt2D(tile.worldPosition.getX(), tile.worldPosition.getY()),
|
npccc.moveTo(new PointInt2D(tile.position.getX(), tile.position.getY()),
|
||||||
(cb)=>{
|
(cb)=>{
|
||||||
console.log(cb);
|
console.log(cb);
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { GameObject } from "../../GameObject/GameObject";
|
import { GameObject } from "../../GameObject/GameObject";
|
||||||
import { PointInt2D } from "../../Utils/Math.utils";
|
import { PointInt2D } from "../../Utils/Math.utils";
|
||||||
import { NavigationPath, PathFinder } from "../../Utils/PathFinding.utils";
|
import { NavigationPath, PathFinder } from "../../Utils/PathFinding.utils";
|
||||||
|
import { findPathOnNavigationGridIfExists } from "../../World/NavigationGrid/NavigationGrid";
|
||||||
import { NPCProto } from "../NPCProto/NPCProto";
|
import { NPCProto } from "../NPCProto/NPCProto";
|
||||||
/**
|
/**
|
||||||
* NPCController defines NPC behavior. Many NPC can have same NPCController for the same behavior.
|
* NPCController defines NPC behavior. Many NPC can have same NPCController for the same behavior.
|
||||||
@ -33,24 +34,28 @@ export class NPCController extends GameObject
|
|||||||
*/
|
*/
|
||||||
moveTo(position, callback)
|
moveTo(position, callback)
|
||||||
{
|
{
|
||||||
let pf = new PathFinder();
|
// let pf = new PathFinder();
|
||||||
let nPath = pf.search(new PointInt2D(this.controlledNPC.worldPosition.getX(), this.controlledNPC.worldPosition.getY()), position);
|
// let nPath = pf.findPathIfExist(new PointInt2D(this.controlledNPC.worldPosition.getX(), this.controlledNPC.worldPosition.getY()), position);
|
||||||
console.log(nPath);
|
let nPath = findPathOnNavigationGridIfExists(new PointInt2D(this.controlledNPC.worldPosition.getX(), this.controlledNPC.worldPosition.getY()), position);
|
||||||
if(nPath.error)
|
nPath.then((r)=>{
|
||||||
|
if(r.error)
|
||||||
{
|
{
|
||||||
callback("failed");
|
callback("failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (nPath.result.path.length < 2)
|
else if (r.result.path.length < 2)
|
||||||
{
|
{
|
||||||
callback("success");
|
callback("success");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (let i = nPath.result.path.length-1; i > 0; i--) {
|
for (let i = r.result.path.length-1; i > 0; i--) {
|
||||||
this.navigationPathQueue.push(nPath.result.path[i]);
|
this.navigationPathQueue.push(r.result.path[i]);
|
||||||
}
|
}
|
||||||
this.navigationCallback = callback;
|
this.navigationCallback = callback;
|
||||||
this.navigationInProgress = true;
|
this.navigationInProgress = true;
|
||||||
|
});
|
||||||
|
// console.log("boba");
|
||||||
|
// console.log(nPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,14 +4,19 @@ import { getTileAt } from "../WorldGeneration/WorldGen";
|
|||||||
import { PointInt2D } from "./Math.utils";
|
import { PointInt2D } from "./Math.utils";
|
||||||
import { SceneObject } from "../SceneObjects/SceneObject";
|
import { SceneObject } from "../SceneObjects/SceneObject";
|
||||||
import { getNavigationGridTile } from "../World/NavigationGrid/NavigationGrid";
|
import { getNavigationGridTile } from "../World/NavigationGrid/NavigationGrid";
|
||||||
|
import { TerrainTile } from "../WorldGeneration/WorldObjects/TerrainTile/TerrainTile";
|
||||||
|
|
||||||
class PathFinderNode {
|
class PathFinderNode {
|
||||||
position;
|
position;
|
||||||
fScore = 0;
|
fScore = 1e16;
|
||||||
gScore = 1e16;
|
gScore = 1e16;
|
||||||
dScore = 1;
|
dScore = 1;
|
||||||
// hScore = 1e16;
|
// hScore = 1e16;
|
||||||
id;
|
id;
|
||||||
|
/**
|
||||||
|
* @type {TerrainTile}
|
||||||
|
*/
|
||||||
|
ref;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -77,12 +82,32 @@ export class PathFinder {
|
|||||||
_goal = new PointInt2D();
|
_goal = new PointInt2D();
|
||||||
_start = new PointInt2D();
|
_start = new PointInt2D();
|
||||||
|
|
||||||
|
#MAX_PATH_ITERATIONS = 10000;
|
||||||
|
#iterationsCounter = 0;
|
||||||
|
|
||||||
|
// findPathIfExist(start, goal)
|
||||||
|
// {
|
||||||
|
// let resultFromGoal = this.search(goal, start);
|
||||||
|
// if(resultFromGoal.state !== 1)
|
||||||
|
// {
|
||||||
|
// return resultFromGoal;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// resultFromGoal.result.path.reverse();
|
||||||
|
// return resultFromGoal;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {PointInt2D} start
|
* @param {PointInt2D} start
|
||||||
* @param {PointInt2D} goal
|
* @param {PointInt2D} goal
|
||||||
*/
|
*/
|
||||||
search(start, goal) {
|
search(start, goal) {
|
||||||
|
this._openSet = [];
|
||||||
|
this._closedSet = [];
|
||||||
|
this.#iterationsCounter = 0;
|
||||||
start.divideBy(BC_TERRAIN_SETTINGS.totalSize);
|
start.divideBy(BC_TERRAIN_SETTINGS.totalSize);
|
||||||
start.multiplyBy(BC_TERRAIN_SETTINGS.totalSize);
|
start.multiplyBy(BC_TERRAIN_SETTINGS.totalSize);
|
||||||
this._start = start;
|
this._start = start;
|
||||||
@ -90,6 +115,7 @@ export class PathFinder {
|
|||||||
goal.divideBy(BC_TERRAIN_SETTINGS.totalSize);
|
goal.divideBy(BC_TERRAIN_SETTINGS.totalSize);
|
||||||
goal.multiplyBy(BC_TERRAIN_SETTINGS.totalSize);
|
goal.multiplyBy(BC_TERRAIN_SETTINGS.totalSize);
|
||||||
this._goal = goal;
|
this._goal = goal;
|
||||||
|
// getNavigationGridTile(goal.getX(), goal.getY()).optionalTerrainTileRef.drawObject.tint = 0x0000FF;
|
||||||
|
|
||||||
this._openSet.push(new PathFinderNode(this._start, 0, this._heuristic(this._start, 0)));
|
this._openSet.push(new PathFinderNode(this._start, 0, this._heuristic(this._start, 0)));
|
||||||
|
|
||||||
@ -110,28 +136,29 @@ export class PathFinder {
|
|||||||
/**
|
/**
|
||||||
* @type Map<String, PathFinderNode>
|
* @type Map<String, PathFinderNode>
|
||||||
*/
|
*/
|
||||||
let cameFrom = new Array();
|
let cameFrom = new Map();
|
||||||
|
|
||||||
let minFScoreNodeIndex = 0;
|
let minFScoreNodeIndex = 0;
|
||||||
//START LOOP WOOOOAAAW
|
//START LOOP WOOOOAAAW
|
||||||
// console.log(goal);
|
|
||||||
while (this._openSet.length > 0) {
|
while (this._openSet.length > 0) {
|
||||||
|
this.#iterationsCounter++;
|
||||||
|
if(this.#iterationsCounter >= this.#MAX_PATH_ITERATIONS)
|
||||||
|
{
|
||||||
|
return new NavigationResult(true, "reached limit", new NavigationPath(), 2);
|
||||||
|
}
|
||||||
//find node with min f score
|
//find node with min f score
|
||||||
//better to rewrite it to priority queue
|
//better to rewrite it to priority queue
|
||||||
|
minFScoreNodeIndex = 0;
|
||||||
for (let i = 0; i < this._openSet.length; i++) {
|
for (let i = 0; i < this._openSet.length; i++) {
|
||||||
// if(!this._openSet[i] || !this._openSet[minFScoreNodeIndex]){
|
|
||||||
// return new NavigationResult(true, "Failed to access element in openSet", undefined);
|
|
||||||
// }
|
|
||||||
if (this._openSet[i].fScore < this._openSet[minFScoreNodeIndex].fScore) minFScoreNodeIndex = i;
|
if (this._openSet[i].fScore < this._openSet[minFScoreNodeIndex].fScore) minFScoreNodeIndex = i;
|
||||||
}
|
}
|
||||||
//wow! node is found and set!!
|
//wow! node is found and set!!
|
||||||
currentNode = this._openSet[minFScoreNodeIndex];
|
currentNode = this._openSet[minFScoreNodeIndex];
|
||||||
minFScoreNodeIndex = 0;
|
// if (currentNode.ref) currentNode.ref.drawObject.tint = 0xff0000;
|
||||||
|
|
||||||
if (PointInt2D.isEqual(currentNode.position, this._goal)) {
|
if (PointInt2D.isEqual(currentNode.position, this._goal)) {
|
||||||
//wow!!! we have found an end of the path!!! this is so cool!!!
|
//wow!!! we have found an end of the path!!! this is so cool!!!
|
||||||
// console.log(cameFrom);
|
return new NavigationResult(false, "", new NavigationPath(this._reconstructPath(cameFrom, currentNode)), 1); //return something weird stuff
|
||||||
return new NavigationResult(false, "", new NavigationPath(this._reconstructPath(cameFrom, currentNode))); //return something weird stuff
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//and now we must delete this node... what a sad situation...
|
//and now we must delete this node... what a sad situation...
|
||||||
@ -144,24 +171,20 @@ export class PathFinder {
|
|||||||
*/
|
*/
|
||||||
let currentNeighbors = this._getNeighbors(currentNode.position);
|
let currentNeighbors = this._getNeighbors(currentNode.position);
|
||||||
for (const neighbor of currentNeighbors) {
|
for (const neighbor of currentNeighbors) {
|
||||||
let tentativeGScore = currentNode.gScore + this._manhattanDistance(currentNode.position, neighbor.position);
|
|
||||||
if (this._existsInClosedSet(neighbor)) continue;
|
if (this._existsInClosedSet(neighbor)) continue;
|
||||||
this._closedSet.push(neighbor);
|
let tentativeGScore = currentNode.gScore + this._manhattanDistance(currentNode.position, neighbor.position);
|
||||||
if (tentativeGScore < neighbor.gScore) {
|
if (tentativeGScore < neighbor.gScore && !this._existsInOpenSet(neighbor)) {
|
||||||
cameFrom.push({ id: neighbor.id, node: currentNode });
|
cameFrom.set(neighbor.id, currentNode);
|
||||||
neighbor.gScore = tentativeGScore;
|
neighbor.gScore = tentativeGScore;
|
||||||
neighbor.fScore = tentativeGScore + this._heuristic(neighbor.position, neighbor.dScore)*0;
|
neighbor.fScore = tentativeGScore + this._heuristic(neighbor.position, neighbor.dScore);
|
||||||
|
if (!this._existsInOpenSet(neighbor)) {
|
||||||
if(!this._existsInOpenSet(neighbor))
|
|
||||||
{
|
|
||||||
this._openSet.push(neighbor);
|
this._openSet.push(neighbor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// console.log([...this._openSet]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NavigationResult(false, "", new NavigationPath());
|
return new NavigationResult(false, "", new NavigationPath(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,12 +195,12 @@ export class PathFinder {
|
|||||||
_reconstructPath(cameFrom, current) {
|
_reconstructPath(cameFrom, current) {
|
||||||
let totalPath = [current.position];
|
let totalPath = [current.position];
|
||||||
console.log(cameFrom);
|
console.log(cameFrom);
|
||||||
// let keys = [...cameFrom.keys()];
|
let keys = [...cameFrom.keys()];
|
||||||
// while (keys.includes(current.id)) {
|
while (keys.includes(current.id)) {
|
||||||
// if (current.id === cameFrom.get(current.id).id) break;
|
if (current.id === cameFrom.get(current.id).id) break;
|
||||||
// current = cameFrom.get(current.id);
|
current = cameFrom.get(current.id);
|
||||||
// totalPath.push(current.position);
|
totalPath.push(current.position);
|
||||||
// }
|
}
|
||||||
return totalPath.reverse();
|
return totalPath.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,39 +217,67 @@ export class PathFinder {
|
|||||||
let currentTile = getNavigationGridTile(root.getX(), root.getY() + BC_TERRAIN_SETTINGS.totalSize);
|
let currentTile = getNavigationGridTile(root.getX(), root.getY() + BC_TERRAIN_SETTINGS.totalSize);
|
||||||
let node;
|
let node;
|
||||||
if (currentTile && !currentTile.isObstacle) {
|
if (currentTile && !currentTile.isObstacle) {
|
||||||
currentTile.optionalTerrainTileRef.drawObject.tint = 0xff0000;
|
// currentTile.optionalTerrainTileRef.drawObject.tint = 0x0000ff;
|
||||||
node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
||||||
if (/*!this._existsInClosedSet(node) &&*/ !currentTile.isObstacle) {
|
node.ref = currentTile.optionalTerrainTileRef;
|
||||||
neighbors.push(node);
|
neighbors.push(node);
|
||||||
}
|
}
|
||||||
}
|
//north-e
|
||||||
|
// currentTile = getNavigationGridTile(root.getX() + BC_TERRAIN_SETTINGS.totalSize, root.getY() + BC_TERRAIN_SETTINGS.totalSize);
|
||||||
|
// if (currentTile && !currentTile.isObstacle) {
|
||||||
|
// // currentTile.optionalTerrainTileRef.drawObject.tint = 0x0000ff;
|
||||||
|
// node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
||||||
|
// node.ref = currentTile.optionalTerrainTileRef;
|
||||||
|
// neighbors.push(node);
|
||||||
|
// }
|
||||||
|
//north-w
|
||||||
|
// currentTile = getNavigationGridTile(root.getX() - BC_TERRAIN_SETTINGS.totalSize, root.getY() + BC_TERRAIN_SETTINGS.totalSize);
|
||||||
|
// if (currentTile && !currentTile.isObstacle) {
|
||||||
|
// // currentTile.optionalTerrainTileRef.drawObject.tint = 0x0000ff;
|
||||||
|
// node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
||||||
|
// node.ref = currentTile.optionalTerrainTileRef;
|
||||||
|
// neighbors.push(node);
|
||||||
|
// }
|
||||||
//south
|
//south
|
||||||
currentTile = getNavigationGridTile(root.getX(), root.getY() - BC_TERRAIN_SETTINGS.totalSize);
|
currentTile = getNavigationGridTile(root.getX(), root.getY() - BC_TERRAIN_SETTINGS.totalSize);
|
||||||
if (currentTile && !currentTile.isObstacle) {
|
if (currentTile && !currentTile.isObstacle) {
|
||||||
currentTile.optionalTerrainTileRef.drawObject.tint = 0xff0000;
|
// currentTile.optionalTerrainTileRef.drawObject.tint = 0x0000ff;
|
||||||
node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
||||||
if (/*!this._existsInClosedSet(node) &&*/ !currentTile.isObstacle) {
|
node.ref = currentTile.optionalTerrainTileRef;
|
||||||
neighbors.push(node);
|
neighbors.push(node);
|
||||||
}
|
}
|
||||||
}
|
//south-e
|
||||||
|
// currentTile = getNavigationGridTile(root.getX() + BC_TERRAIN_SETTINGS.totalSize, root.getY() - BC_TERRAIN_SETTINGS.totalSize);
|
||||||
|
// if (currentTile && !currentTile.isObstacle) {
|
||||||
|
// // currentTile.optionalTerrainTileRef.drawObject.tint = 0x0000ff;
|
||||||
|
// node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
||||||
|
// node.ref = currentTile.optionalTerrainTileRef;
|
||||||
|
// neighbors.push(node);
|
||||||
|
// }
|
||||||
|
//south-w
|
||||||
|
// currentTile = getNavigationGridTile(root.getX() - BC_TERRAIN_SETTINGS.totalSize, root.getY() - BC_TERRAIN_SETTINGS.totalSize);
|
||||||
|
// if (currentTile && !currentTile.isObstacle) {
|
||||||
|
// // currentTile.optionalTerrainTileRef.drawObject.tint = 0x0000ff;
|
||||||
|
// node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
||||||
|
// node.ref = currentTile.optionalTerrainTileRef;
|
||||||
|
// neighbors.push(node);
|
||||||
|
// }
|
||||||
//east
|
//east
|
||||||
currentTile = getNavigationGridTile(root.getX() + BC_TERRAIN_SETTINGS.totalSize, root.getY());
|
currentTile = getNavigationGridTile(root.getX() + BC_TERRAIN_SETTINGS.totalSize, root.getY());
|
||||||
if (currentTile && !currentTile.isObstacle) {
|
if (currentTile && !currentTile.isObstacle) {
|
||||||
currentTile.optionalTerrainTileRef.drawObject.tint = 0xff0000;
|
// currentTile.optionalTerrainTileRef.drawObject.tint = 0x0000ff;
|
||||||
node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
||||||
if (/*!this._existsInClosedSet(node) &&*/ !currentTile.isObstacle) {
|
node.ref = currentTile.optionalTerrainTileRef;
|
||||||
neighbors.push(node);
|
neighbors.push(node);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//west
|
//west
|
||||||
currentTile = getNavigationGridTile(root.getX() - BC_TERRAIN_SETTINGS.totalSize, root.getY());
|
currentTile = getNavigationGridTile(root.getX() - BC_TERRAIN_SETTINGS.totalSize, root.getY());
|
||||||
if (currentTile && !currentTile.isObstacle) {
|
if (currentTile && !currentTile.isObstacle) {
|
||||||
currentTile.optionalTerrainTileRef.drawObject.tint = 0xff0000;
|
// currentTile.optionalTerrainTileRef.drawObject.tint = 0x0000ff;
|
||||||
node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
node = new PathFinderNode(currentTile.position, 1e16, 1e16, currentTile.movementCost);
|
||||||
if (/*!this._existsInClosedSet(node) &&*/ !currentTile.isObstacle) {
|
node.ref = currentTile.optionalTerrainTileRef;
|
||||||
neighbors.push(node);
|
neighbors.push(node);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return neighbors;
|
return neighbors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,12 +285,24 @@ export class PathFinder {
|
|||||||
*
|
*
|
||||||
* @param {PointInt2D} start
|
* @param {PointInt2D} start
|
||||||
* @param {PointInt2D} goal
|
* @param {PointInt2D} goal
|
||||||
* @returns
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
_manhattanDistance(start, goal) {
|
_manhattanDistance(start, goal) {
|
||||||
return Math.abs(start.getX() - goal.getX()) + Math.abs(start.getY() - goal.getY());
|
return Math.abs(start.getX() - goal.getX()) + Math.abs(start.getY() - goal.getY());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {PointInt2D} start
|
||||||
|
* @param {PointInt2D} goal
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
_euclideanDistance(start, goal) {
|
||||||
|
let dx = Math.abs(start.getX() - goal.getX());
|
||||||
|
let dy = Math.abs(start.getY() - goal.getY());
|
||||||
|
return Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {PointInt2D} current
|
* @param {PointInt2D} current
|
||||||
@ -251,7 +314,8 @@ export class PathFinder {
|
|||||||
let x2 = this._start.getX() - this._goal.getX();
|
let x2 = this._start.getX() - this._goal.getX();
|
||||||
let y2 = this._start.getY() - this._goal.getY();
|
let y2 = this._start.getY() - this._goal.getY();
|
||||||
let cross = Math.abs(x1 * y2 - x2 * y1);
|
let cross = Math.abs(x1 * y2 - x2 * y1);
|
||||||
return this._manhattanDistance(current, this._goal) * d;
|
// console.log("cross", cross);
|
||||||
|
return this._manhattanDistance(current, this._goal) * d + cross * 0.00001;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { PointInt2D } from "../../Utils/Math.utils";
|
import { PointInt2D } from "../../Utils/Math.utils";
|
||||||
|
import { PathFinder } from "../../Utils/PathFinding.utils";
|
||||||
import { getWorldChunkAt, worldCoordinatesToChunkLocalCoordinates } from "../../WorldGeneration/WorldGen";
|
import { getWorldChunkAt, worldCoordinatesToChunkLocalCoordinates } from "../../WorldGeneration/WorldGen";
|
||||||
import { TerrainTile } from "../../WorldGeneration/WorldObjects/TerrainTile/TerrainTile";
|
import { TerrainTile } from "../../WorldGeneration/WorldObjects/TerrainTile/TerrainTile";
|
||||||
|
|
||||||
@ -80,25 +81,30 @@ export class NavigationGridChunk
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class NavigationGrid
|
// export class NavigationGrid
|
||||||
{
|
// {
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// * @param {Number} xWorld
|
||||||
|
// * @param {Number} yWorld
|
||||||
|
// */
|
||||||
|
// static getNavigationGridTile(xWorld, yWorld)
|
||||||
|
// {
|
||||||
|
// let chunk = getWorldChunkAt(xWorld, yWorld);
|
||||||
|
// if(chunk)
|
||||||
|
// {
|
||||||
|
// return chunk.navigationGridChunk.getFromChunk(xWorld, yWorld);
|
||||||
|
// }
|
||||||
|
// return undefined;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param {Number} xWorld
|
* @param {Number} xWorld
|
||||||
* @param {Number} yWorld
|
* @param {Number} yWorld
|
||||||
|
* @returns
|
||||||
*/
|
*/
|
||||||
static getNavigationGridTile(xWorld, yWorld)
|
|
||||||
{
|
|
||||||
let chunk = getWorldChunkAt(xWorld, yWorld);
|
|
||||||
if(chunk)
|
|
||||||
{
|
|
||||||
return chunk.navigationGridChunk.getFromChunk(xWorld, yWorld);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getNavigationGridTile(xWorld, yWorld)
|
export function getNavigationGridTile(xWorld, yWorld)
|
||||||
{
|
{
|
||||||
let chunk = getWorldChunkAt(xWorld, yWorld);
|
let chunk = getWorldChunkAt(xWorld, yWorld);
|
||||||
@ -108,3 +114,26 @@ export function getNavigationGridTile(xWorld, yWorld)
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NavigationGridPathFinderCallback(result) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _findPathAsync(start, goal)
|
||||||
|
{
|
||||||
|
let pf = new PathFinder();
|
||||||
|
return pf.search(start, goal);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {PointInt2D} start
|
||||||
|
* @param {PointInt2D} goal
|
||||||
|
*/
|
||||||
|
export async function findPathOnNavigationGridIfExists(start, goal) {
|
||||||
|
let r0 = await _findPathAsync(goal, start);
|
||||||
|
if(!r0.error){
|
||||||
|
r0.result.path.reverse();
|
||||||
|
return r0;
|
||||||
|
}
|
||||||
|
let r1 = await _findPathAsync(start, goal);
|
||||||
|
return r1;
|
||||||
|
}
|
@ -8,7 +8,7 @@ import { Point2D, PointInt2D, clampNumber } from "../Utils/Math.utils";
|
|||||||
import { addGameObjectToGameState } from "../GameState/GameState";
|
import { addGameObjectToGameState } from "../GameState/GameState";
|
||||||
import { VegetationTile, VegetationTileProps } from "./WorldObjects/VegetationTile/VegetationTile";
|
import { VegetationTile, VegetationTileProps } from "./WorldObjects/VegetationTile/VegetationTile";
|
||||||
import { WorldChunksVisibilityUpdater } from "./WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater";
|
import { WorldChunksVisibilityUpdater } from "./WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater";
|
||||||
import { NavigationGrid, NavigationGridChunk, NavigationGridTile } from "../World/NavigationGrid/NavigationGrid";
|
import { NavigationGridChunk, NavigationGridTile } from "../World/NavigationGrid/NavigationGrid";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type Map<String, WorldChunk>
|
* @type Map<String, WorldChunk>
|
||||||
@ -30,8 +30,8 @@ const terrainTypeList = {
|
|||||||
};
|
};
|
||||||
const terrainNavigationCostList = {
|
const terrainNavigationCostList = {
|
||||||
0: 100000000000, //water
|
0: 100000000000, //water
|
||||||
1: 1, //sand
|
1: 3, //sand
|
||||||
2: 1, //grass
|
2: 2, //grass
|
||||||
3: 1, //stone
|
3: 1, //stone
|
||||||
};
|
};
|
||||||
const grassVegetationSpriteList = {
|
const grassVegetationSpriteList = {
|
||||||
@ -78,6 +78,7 @@ const grassVegResourcesList = {
|
|||||||
export function worldCoordinatesToChunkIndex(x, y) {
|
export function worldCoordinatesToChunkIndex(x, y) {
|
||||||
let w = BC_CHUNKS_SETTINGS.width * BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
let w = BC_CHUNKS_SETTINGS.width * BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
||||||
let h = BC_CHUNKS_SETTINGS.height * BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
let h = BC_CHUNKS_SETTINGS.height * BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
||||||
|
// console.log(w, h);
|
||||||
return { x: Math.floor(x / w), y: Math.floor(y / h) };
|
return { x: Math.floor(x / w), y: Math.floor(y / h) };
|
||||||
}
|
}
|
||||||
export function worldCoordinatesToChunkIndexesCoordinates(x, y) {
|
export function worldCoordinatesToChunkIndexesCoordinates(x, y) {
|
||||||
@ -126,7 +127,7 @@ export function getWorldChunkById(id) {
|
|||||||
* @param {Number} xWorld
|
* @param {Number} xWorld
|
||||||
* @param {Number} yWorld
|
* @param {Number} yWorld
|
||||||
* @param {ChunkStorageTypes} storageType
|
* @param {ChunkStorageTypes} storageType
|
||||||
* @returns
|
* @returns {}
|
||||||
*/
|
*/
|
||||||
export function getTileAt(xWorld, yWorld, storageType) {
|
export function getTileAt(xWorld, yWorld, storageType) {
|
||||||
let c = getWorldChunkAt(xWorld, yWorld);
|
let c = getWorldChunkAt(xWorld, yWorld);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user