NPC
This commit is contained in:
parent
6e33c8a99c
commit
2a69d4ad25
@ -3,14 +3,14 @@ import { UICameraInfo } from "../UIPipes/UIPipes";
|
|||||||
import { interpolate, interpolateCos } from "../Utils/Math.utils";
|
import { interpolate, interpolateCos } from "../Utils/Math.utils";
|
||||||
|
|
||||||
export function moveVertically(tick, keyCode) {
|
export function moveVertically(tick, keyCode) {
|
||||||
BC_CAMERA.position.y += (tick.deltaMS / 1000) * 800 * (keyCode === "KeyS" ? 1 : -1);
|
BC_CAMERA.position.y += (tick.deltaMS / 1000) * 1800 * (keyCode === "KeyS" ? 1 : -1);
|
||||||
UICameraInfo.update((s) => {
|
UICameraInfo.update((s) => {
|
||||||
s.position.y = BC_CAMERA.position.y;
|
s.position.y = BC_CAMERA.position.y;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function moveHorizontally(tick, keyCode) {
|
export function moveHorizontally(tick, keyCode) {
|
||||||
BC_CAMERA.position.x += (tick.deltaMS / 1000) * 800 * (keyCode === "KeyD" ? 1 : -1);
|
BC_CAMERA.position.x += (tick.deltaMS / 1000) * 1800 * (keyCode === "KeyD" ? 1 : -1);
|
||||||
UICameraInfo.update((s) => {
|
UICameraInfo.update((s) => {
|
||||||
s.position.x = BC_CAMERA.position.x;
|
s.position.x = BC_CAMERA.position.x;
|
||||||
});
|
});
|
||||||
|
@ -60,11 +60,17 @@ function setupInGameSelector() {
|
|||||||
sprite0.position.set(t.x, t.y);
|
sprite0.position.set(t.x, t.y);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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);
|
||||||
// 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);
|
||||||
|
if(tile.props.navigationCost > 10) return;
|
||||||
|
npccc.moveTo(new PointInt2D(tile.worldPosition.getX(), tile.worldPosition.getY()),
|
||||||
|
(cb)=>{
|
||||||
|
console.log(cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,8 +103,8 @@ export async function initGame() {
|
|||||||
|
|
||||||
setBC_CURRENT_SCENE(new GameScene());
|
setBC_CURRENT_SCENE(new GameScene());
|
||||||
|
|
||||||
BC_CAMERA.position.x = Math.floor(PRNG() * 3242 - 372);
|
// BC_CAMERA.position.x = Math.floor(PRNG() * 3242 - 372);
|
||||||
BC_CAMERA.position.y = Math.floor(PRNG() * 1285 - 255);
|
// BC_CAMERA.position.y = Math.floor(PRNG() * 1285 - 255);
|
||||||
|
|
||||||
UICameraInfo.update((s)=>{
|
UICameraInfo.update((s)=>{
|
||||||
s.position.x = BC_CAMERA.position.x;
|
s.position.x = BC_CAMERA.position.x;
|
||||||
@ -136,18 +142,21 @@ function startGame() {
|
|||||||
|
|
||||||
createFirstWorldChunks();
|
createFirstWorldChunks();
|
||||||
|
|
||||||
let testNPCController = new NPCController();
|
let testNPCController = new NPCController(true);
|
||||||
let testNPC = new NPCProto(true, testNPCController);
|
let testNPC = new NPCProto(true, testNPCController);
|
||||||
testNPC.spriteSheetPath = "assets/images/characters/char0.png";
|
testNPC.spriteSheetPath = "assets/images/characters/char0.png";
|
||||||
testNPC.frame = new PIXI.Rectangle(0, 0, 16, 16);
|
testNPC.frame = new PIXI.Rectangle(0, 0, 16, 16);
|
||||||
testNPC.controller = testNPCController;
|
testNPC.controller = testNPCController;
|
||||||
|
testNPC.worldPosition = new PointInt2D(0,0);
|
||||||
testNPCController.controlledNPC = testNPC;
|
testNPCController.controlledNPC = testNPC;
|
||||||
addGameObjectToGameState(testNPCController);
|
addGameObjectToGameState(testNPCController);
|
||||||
BC_CURRENT_SCENE.addObjectToSceneWithInitialization(testNPC);
|
BC_CURRENT_SCENE.addObjectToSceneWithInitialization(testNPC);
|
||||||
testNPC.drawObject.zIndex = 4;
|
testNPC.drawObject.zIndex = 4;
|
||||||
testNPC.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
testNPC.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
||||||
npccc = testNPCController;
|
npccc = testNPCController;
|
||||||
let pf = new PathFinder();
|
// let pf = new PathFinder();
|
||||||
let dest = pf.search(new PointInt2D(), new PointInt2D(10, 10));
|
// setTimeout(()=>{
|
||||||
testNPCController.moveTo(new Point2D(dest.worldPosition.getX(), dest.worldPosition.getY()));
|
// console.log(pf.search(new PointInt2D(), new PointInt2D(0, 0)));
|
||||||
|
// }, 1);
|
||||||
|
// testNPCController.moveTo(new Point2D(dest.worldPosition.getX(), dest.worldPosition.getY()));
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,8 @@ export function setBC_NPC_LAYER(npc_layer) {
|
|||||||
// export let BC_TERRAIN;
|
// export let BC_TERRAIN;
|
||||||
export let BC_TERRAIN_SETTINGS = {
|
export let BC_TERRAIN_SETTINGS = {
|
||||||
tileSize: 16,
|
tileSize: 16,
|
||||||
scale: 8.0
|
scale: 8.0,
|
||||||
|
totalSize: 16*8.0
|
||||||
}
|
}
|
||||||
// export let BC_TERRAIN_VAULT = {};
|
// export let BC_TERRAIN_VAULT = {};
|
||||||
// export function setBC_TERRAIN(terrain) {
|
// export function setBC_TERRAIN(terrain) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { GameObject } from "../../GameObject/GameObject";
|
import { GameObject } from "../../GameObject/GameObject";
|
||||||
import { Point2D } from "../../Utils/Math.utils";
|
import { PointInt2D } from "../../Utils/Math.utils";
|
||||||
|
import { NavigationPath, PathFinder } from "../../Utils/PathFinding.util";
|
||||||
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.
|
||||||
@ -12,18 +13,87 @@ export class NPCController extends GameObject
|
|||||||
*/
|
*/
|
||||||
controlledNPC = null;
|
controlledNPC = null;
|
||||||
|
|
||||||
constructor(tickAble = false)
|
/**
|
||||||
|
* @type Array<PointInt2D>
|
||||||
|
*/
|
||||||
|
navigationPathQueue = new Array();
|
||||||
|
navigationInProgress = false;
|
||||||
|
navigationFollowMidPoint = false;
|
||||||
|
navigationCallback = ()=>{};
|
||||||
|
|
||||||
|
constructor(tickAble = true)
|
||||||
{
|
{
|
||||||
super(tickAble);
|
super(tickAble);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* moves NPC to position
|
* moves NPC to position
|
||||||
* @param {Point2D} position
|
* @param {PointInt2D} position
|
||||||
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
moveTo(position)
|
moveTo(position, callback)
|
||||||
{
|
{
|
||||||
this.controlledNPC.currentPosition = position;
|
let pf = new PathFinder();
|
||||||
this.controlledNPC.currentPosition = position;
|
let nPath = pf.search(new PointInt2D(this.controlledNPC.worldPosition.getX(), this.controlledNPC.worldPosition.getY()), position);
|
||||||
|
if(!nPath)
|
||||||
|
{
|
||||||
|
console.log("failed");
|
||||||
|
callback("failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (nPath.path.length < 2)
|
||||||
|
{
|
||||||
|
console.log("success");
|
||||||
|
callback("success");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i = nPath.path.length-1; i > 0; i--) {
|
||||||
|
this.navigationPathQueue.push(nPath.path[i]);
|
||||||
|
}
|
||||||
|
this.navigationCallback = callback;
|
||||||
|
this.navigationInProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {NavigationPath} pathToFollow
|
||||||
|
* @param {Function} callback
|
||||||
|
*/
|
||||||
|
_moveByPath(pathToFollow, callback)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tick(ticker)
|
||||||
|
{
|
||||||
|
// console.log("object");
|
||||||
|
if(this.navigationInProgress)
|
||||||
|
{
|
||||||
|
if(!this.navigationFollowMidPoint)
|
||||||
|
{
|
||||||
|
let target = this.navigationPathQueue.pop();
|
||||||
|
if(!target)
|
||||||
|
{
|
||||||
|
this.navigationInProgress = false;
|
||||||
|
this.navigationCallback("success");
|
||||||
|
console.log("success");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.controlledNPC.worldPosition = target;
|
||||||
|
this.navigationFollowMidPoint = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(
|
||||||
|
Math.abs(this.controlledNPC.drawObject.x - this.controlledNPC.worldPosition.getX()) < 0.5 &&
|
||||||
|
Math.abs(this.controlledNPC.drawObject.y - this.controlledNPC.worldPosition.getY()) < 0.5
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.navigationFollowMidPoint = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -12,12 +12,7 @@ export class NPCProto extends SceneObject
|
|||||||
*/
|
*/
|
||||||
controller = null;
|
controller = null;
|
||||||
|
|
||||||
/**
|
_positionInterpolationSpeed = 30;
|
||||||
* NPC position in world
|
|
||||||
*/
|
|
||||||
currentPosition = new Point2D();
|
|
||||||
|
|
||||||
_positionInterpolationSpeed = 10;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* path to NPC spritesheet
|
* path to NPC spritesheet
|
||||||
@ -54,7 +49,7 @@ export class NPCProto extends SceneObject
|
|||||||
_positionInterpolation(delta)
|
_positionInterpolation(delta)
|
||||||
{
|
{
|
||||||
let {x, y} = this.drawObject.position;
|
let {x, y} = this.drawObject.position;
|
||||||
this.drawObject.position.set(interpolate(x, this.currentPosition.getX(), delta), interpolate(y, this.currentPosition.getY(), delta));
|
this.drawObject.position.set(interpolate(x, this.worldPosition.getX(), delta), interpolate(y, this.worldPosition.getY(), delta));
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import { GameObject } from "../GameObject/GameObject";
|
import { GameObject } from "../GameObject/GameObject";
|
||||||
import { Container } from "../../pixi/pixi.mjs";
|
import { Container } from "../../pixi/pixi.mjs";
|
||||||
import { Point2D } from "../Utils/Math.utils";
|
import { Point2D, PointInt2D } from "../Utils/Math.utils";
|
||||||
|
|
||||||
export class SceneObject extends GameObject {
|
export class SceneObject extends GameObject {
|
||||||
/**
|
/**
|
||||||
@ -17,7 +17,7 @@ export class SceneObject extends GameObject {
|
|||||||
/**
|
/**
|
||||||
* world position for scene object
|
* world position for scene object
|
||||||
*/
|
*/
|
||||||
worldPosition = new Point2D();
|
worldPosition = new PointInt2D();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -73,6 +73,41 @@ export class PointInt2D
|
|||||||
this.#y = Math.floor(y);
|
this.#y = Math.floor(y);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Number} x
|
||||||
|
*/
|
||||||
|
divideBy(x)
|
||||||
|
{
|
||||||
|
if(x > 0)
|
||||||
|
{
|
||||||
|
this.#x = Math.floor(this.#x / x);
|
||||||
|
this.#y = Math.floor(this.#y / x);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (x < 0)
|
||||||
|
{
|
||||||
|
this.#x = Math.ceil(this.#x / x);
|
||||||
|
this.#y = Math.ceil(this.#y / x);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
multiplyBy(x)
|
||||||
|
{
|
||||||
|
if(x >= 0)
|
||||||
|
{
|
||||||
|
this.#x = Math.floor(this.#x * x);
|
||||||
|
this.#y = Math.floor(this.#y * x);
|
||||||
|
}
|
||||||
|
else if (x < 0)
|
||||||
|
{
|
||||||
|
this.#x = Math.ceil(this.#x * x);
|
||||||
|
this.#y = Math.ceil(this.#y * x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {PointInt2D} a
|
* @param {PointInt2D} a
|
||||||
|
@ -2,71 +2,106 @@ import { BC_TERRAIN_SETTINGS } from "../GlobalVariables/GlobalVariables";
|
|||||||
import { ChunkStorageTypes } from "../WorldGeneration/WorldChunk/WorldGenChunk";
|
import { ChunkStorageTypes } from "../WorldGeneration/WorldChunk/WorldGenChunk";
|
||||||
import { getTileAt } from "../WorldGeneration/WorldGen";
|
import { getTileAt } from "../WorldGeneration/WorldGen";
|
||||||
import { PointInt2D } from "./Math.utils";
|
import { PointInt2D } from "./Math.utils";
|
||||||
import { TerrainTile } from "../WorldGeneration/WorldObjects/TerrainTile/TerrainTile";
|
import { SceneObject } from "../SceneObjects/SceneObject";
|
||||||
|
|
||||||
class PathFinderNode
|
class PathFinderNode {
|
||||||
{
|
|
||||||
position;
|
position;
|
||||||
fScore;
|
fScore = 0;
|
||||||
neighbors;
|
gScore = 1e16;
|
||||||
|
dScore = 1;
|
||||||
|
// hScore = 1e16;
|
||||||
|
id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {PointInt2D} position
|
* @param {PointInt2D} position
|
||||||
* @param {Number} fScore
|
* @param {Number} gScore
|
||||||
*/
|
*/
|
||||||
constructor(position, fScore)
|
constructor(position, gScore = 1e16, fScore = 1e16, dScore) {
|
||||||
{
|
|
||||||
this.position = position;
|
this.position = position;
|
||||||
|
this.id = position.getX() + "_" + position.getY();
|
||||||
|
this.gScore = gScore;
|
||||||
this.fScore = fScore;
|
this.fScore = fScore;
|
||||||
|
this.dScore = dScore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class NavigationPath {
|
||||||
|
path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array<PointInt2D>} path
|
||||||
|
*/
|
||||||
|
constructor(path = [])
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export class PathFinder
|
export class PathFinder {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* @type Array<PathFinderNode>
|
* @type Array<PathFinderNode>
|
||||||
*/
|
*/
|
||||||
_openSet = new Array();
|
_openSet = new Array();
|
||||||
_closedSet = new Array();
|
_closedSet = new Array();
|
||||||
|
|
||||||
|
_goal = new PointInt2D();
|
||||||
|
_start = new PointInt2D();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {PointInt2D} start
|
* @param {PointInt2D} start
|
||||||
* @param {PointInt2D} goal
|
* @param {PointInt2D} goal
|
||||||
*/
|
*/
|
||||||
search(start, goal)
|
search(start, goal) {
|
||||||
{
|
start.divideBy(BC_TERRAIN_SETTINGS.totalSize);
|
||||||
this._openSet.push(new PathFinderNode(start, 0));
|
start.multiplyBy(BC_TERRAIN_SETTINGS.totalSize);
|
||||||
|
this._start = start;
|
||||||
|
|
||||||
|
goal.divideBy(BC_TERRAIN_SETTINGS.totalSize);
|
||||||
|
goal.multiplyBy(BC_TERRAIN_SETTINGS.totalSize);
|
||||||
|
this._goal = goal;
|
||||||
|
|
||||||
|
this._openSet.push(new PathFinderNode(this._start, 0, this._heuristic(this._start, 0)));
|
||||||
|
|
||||||
//code
|
//code
|
||||||
|
/**
|
||||||
|
* @type PathFinderNode
|
||||||
|
*/
|
||||||
|
let currentNode;
|
||||||
|
// /**
|
||||||
|
// * @type Map<String, Number>
|
||||||
|
// */
|
||||||
|
// let gScores = new Map();
|
||||||
|
// /**
|
||||||
|
// * @type Map<String, Number>
|
||||||
|
// */
|
||||||
|
// let fScores = new Map();
|
||||||
|
|
||||||
let currentNode = new PathFinderNode(new PointInt2D(), 0);
|
|
||||||
/**
|
/**
|
||||||
* @type Map<String, Number>
|
* @type Map<String, PathFinderNode>
|
||||||
*/
|
*/
|
||||||
let gScores = new Map();
|
let cameFrom = new Map();
|
||||||
/**
|
|
||||||
* @type Map<String, Number>
|
|
||||||
*/
|
|
||||||
let fScores = 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) {
|
||||||
//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
|
||||||
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])
|
if(!this._openSet[i]){
|
||||||
minFScoreNodeIndex = i;
|
return undefined;
|
||||||
|
}
|
||||||
|
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];
|
||||||
|
|
||||||
if(PointInt2D.isEqual(currentNode.position, 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!!!
|
||||||
return 1111; //return something weird stuff
|
// console.log(cameFrom);
|
||||||
|
return 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...
|
||||||
@ -75,21 +110,131 @@ export class PathFinder
|
|||||||
this._closedSet.push(currentNode);
|
this._closedSet.push(currentNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type TerrainTile
|
* @type Array<PathFinderNode>
|
||||||
*/
|
*/
|
||||||
let neighbors = this._getNeighbors(currentNode.position);
|
let currentNeighbors = this._getNeighbors(currentNode.position);
|
||||||
return neighbors;
|
if(!currentNeighbors) return undefined;
|
||||||
|
// console.log(currentNeighbors);
|
||||||
|
for (const neighbor of currentNeighbors) {
|
||||||
|
this._closedSet.push(neighbor);
|
||||||
|
let tentativeGScore = currentNode.gScore + this._manhattanDistance(currentNode.position, neighbor.position);
|
||||||
|
if (tentativeGScore < neighbor.gScore) {
|
||||||
|
// console.log(neighbor.id, currentNode.id);
|
||||||
|
cameFrom.set(neighbor.id, currentNode);
|
||||||
|
neighbor.gScore = tentativeGScore;
|
||||||
|
neighbor.fScore = tentativeGScore + this._heuristic(neighbor.position, neighbor.dScore);
|
||||||
|
|
||||||
|
let neighborFoundInOpenSet = false;
|
||||||
|
for (const node of this._openSet) {
|
||||||
|
if (node.id === neighbor.id) {
|
||||||
|
neighborFoundInOpenSet = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!neighborFoundInOpenSet) this._openSet.push(neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Map<String, PathFinderNode>} cameFrom
|
||||||
|
* @param {PathFinderNode} current
|
||||||
|
*/
|
||||||
|
_reconstructPath(cameFrom, current) {
|
||||||
|
// console.log(cameFrom);
|
||||||
|
let totalPath = [current.position];
|
||||||
|
let keys = [...cameFrom.keys()];
|
||||||
|
while (keys.includes(current.id)) {
|
||||||
|
current = cameFrom.get(current.id);
|
||||||
|
totalPath.push(current.position);
|
||||||
|
}
|
||||||
|
return totalPath.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {PointInt2D} root
|
* @param {PointInt2D} root
|
||||||
*/
|
*/
|
||||||
_getNeighbors(root)
|
_getNeighbors(root) {
|
||||||
{
|
/**
|
||||||
let neighborNorth = getTileAt(root.getX(), root.getY() - BC_TERRAIN_SETTINGS.tileSize*BC_TERRAIN_SETTINGS.scale, ChunkStorageTypes.TYPE_TERRAIN);
|
* @type Array<PathFinderNode>
|
||||||
return neighborNorth;
|
*/
|
||||||
//TODO
|
let neighbors = new Array();
|
||||||
|
/**
|
||||||
|
* @type SceneObject
|
||||||
|
*/
|
||||||
|
let currentTile = getTileAt(root.getX(), root.getY() + BC_TERRAIN_SETTINGS.totalSize, ChunkStorageTypes.TYPE_TERRAIN);
|
||||||
|
if(!currentTile) return undefined;
|
||||||
|
// currentTile.drawObject.tint = 0xff0000;
|
||||||
|
let node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost);
|
||||||
|
//north
|
||||||
|
if (!this._existsInClosedSet(node)) {
|
||||||
|
neighbors.push(node);
|
||||||
}
|
}
|
||||||
};
|
//south
|
||||||
|
currentTile = getTileAt(root.getX(), root.getY() - BC_TERRAIN_SETTINGS.totalSize, ChunkStorageTypes.TYPE_TERRAIN);
|
||||||
|
if(!currentTile) return undefined;
|
||||||
|
// currentTile.drawObject.tint = 0xff0000;
|
||||||
|
node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost);
|
||||||
|
if (!this._existsInClosedSet(node)) {
|
||||||
|
neighbors.push(node);
|
||||||
|
}
|
||||||
|
//east
|
||||||
|
currentTile = getTileAt(root.getX() + BC_TERRAIN_SETTINGS.totalSize, root.getY(), ChunkStorageTypes.TYPE_TERRAIN);
|
||||||
|
if(!currentTile) return undefined;
|
||||||
|
// currentTile.drawObject.tint = 0xff0000;
|
||||||
|
node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost);
|
||||||
|
if (!this._existsInClosedSet(node)) {
|
||||||
|
neighbors.push(node);
|
||||||
|
}
|
||||||
|
//west
|
||||||
|
currentTile = getTileAt(root.getX() - BC_TERRAIN_SETTINGS.totalSize, root.getY(), ChunkStorageTypes.TYPE_TERRAIN);
|
||||||
|
if(!currentTile) return undefined;
|
||||||
|
// currentTile.drawObject.tint = 0xff0000;
|
||||||
|
node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost);
|
||||||
|
if (!this._existsInClosedSet(node)) {
|
||||||
|
neighbors.push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighbors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {PointInt2D} start
|
||||||
|
* @param {PointInt2D} goal
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
_manhattanDistance(start, goal) {
|
||||||
|
return Math.abs(start.getX() - goal.getX()) + Math.abs(start.getY() - goal.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {PointInt2D} current
|
||||||
|
* @param {Number} d
|
||||||
|
*/
|
||||||
|
_heuristic(current, d) {
|
||||||
|
let x1 = current.getX() - this._goal.getX();
|
||||||
|
let y1 = current.getY() - this._goal.getY();
|
||||||
|
let x2 = this._start.getX() - this._goal.getX();
|
||||||
|
let y2 = this._start.getY() - this._goal.getY();
|
||||||
|
let cross = Math.abs(x1*y2 - x2*y1);
|
||||||
|
return this._manhattanDistance(current, this._goal) * d + cross*0.001;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {PathFinderNode} node
|
||||||
|
*/
|
||||||
|
_existsInClosedSet(node) {
|
||||||
|
for (const i of this._closedSet) {
|
||||||
|
if (i.id === node.id) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -150,7 +150,7 @@ let noise = new Noise(Math.floor(PRNG() * 188822321));
|
|||||||
let noiseErosion = new Noise(Math.floor(PRNG() * 327749029));
|
let noiseErosion = new Noise(Math.floor(PRNG() * 327749029));
|
||||||
let noiseBiomes = new Noise(Math.floor(PRNG() * 927472011));
|
let noiseBiomes = new Noise(Math.floor(PRNG() * 927472011));
|
||||||
|
|
||||||
let terrainCue = new NumberCue([0, 1, 2, 3, 3], [0.0, 0.45, 0.5, 0.9, 1.0]);
|
let terrainCue = new NumberCue([0, 1, 2, 3, 3], [0.0, 0.2, 0.25, 0.9, 1.0]);
|
||||||
let terrainTintCue = new NumberCue([0.9, 1, 1, 0.95, 0.9, 1, 0.93, 1], [0.0, 0.45, 0.45, 0.5, 0.5, 0.9, 0.9, 1.0]);
|
let terrainTintCue = new NumberCue([0.9, 1, 1, 0.95, 0.9, 1, 0.93, 1], [0.0, 0.45, 0.45, 0.5, 0.5, 0.9, 0.9, 1.0]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,8 +223,8 @@ export function fillWorldGenChunk(chunk, x, y) {
|
|||||||
export function createFirstWorldChunks() {
|
export function createFirstWorldChunks() {
|
||||||
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;
|
||||||
for (let i = -1; i < 2; i++) {
|
for (let i = -2; i < 3; i++) {
|
||||||
for (let j = -1; j < 2; j++) {
|
for (let j = -2; j < 3; j++) {
|
||||||
let chunkXCeiled = Math.floor((BC_CAMERA.position.x + w * i) / w);
|
let chunkXCeiled = Math.floor((BC_CAMERA.position.x + w * i) / w);
|
||||||
let chunkYCeiled = Math.floor((BC_CAMERA.position.y + h * j) / h);
|
let chunkYCeiled = Math.floor((BC_CAMERA.position.y + h * j) / h);
|
||||||
let chunkId = chunkXCeiled + "_" + chunkYCeiled;
|
let chunkId = chunkXCeiled + "_" + chunkYCeiled;
|
||||||
|
@ -109,6 +109,7 @@ export function search() {
|
|||||||
let neighbors = current.neighbors;
|
let neighbors = current.neighbors;
|
||||||
|
|
||||||
for (let i = 0; i < neighbors.length; i++) {
|
for (let i = 0; i < neighbors.length; i++) {
|
||||||
|
// console.log(neighbors.length);
|
||||||
let neighbor = neighbors[i];
|
let neighbor = neighbors[i];
|
||||||
|
|
||||||
if (!closedSet.includes(neighbor)) {
|
if (!closedSet.includes(neighbor)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user