fixed day-night cycle colors and changed world generation
This commit is contained in:
parent
78686fd323
commit
b4c6b97ca4
@ -74,6 +74,9 @@
|
|||||||
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">
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { BC_CAMERA, BC_VIEWPORT } from "../GlobalVariables/GlobalVariables";
|
import { BC_CAMERA, BC_VIEWPORT } from "../GlobalVariables/GlobalVariables";
|
||||||
import { UICameraInfo } from "../UIPipes/UIPipes";
|
import { UICameraInfo } from "../UIPipes/UIPipes";
|
||||||
|
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) * 800 * (keyCode === "KeyS" ? 1 : -1);
|
||||||
@ -15,8 +16,9 @@ export function moveHorizontally(tick, keyCode) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculateViewportFromCamera() {
|
export function calculateViewportFromCamera(tick) {
|
||||||
// BC_VIEWPORT.pivot.set(0.5, 0.5);
|
// BC_VIEWPORT.pivot.set(0.5, 0.5);
|
||||||
|
BC_CAMERA.zoom = interpolate(BC_CAMERA.zoom, BC_CAMERA.targetZoom, (tick.deltaMS / 1000) * 45);
|
||||||
BC_VIEWPORT.position.set(
|
BC_VIEWPORT.position.set(
|
||||||
Math.floor(((window.innerWidth / 2.0 / BC_CAMERA.zoom) - BC_CAMERA.position.x) * BC_CAMERA.zoom),
|
Math.floor(((window.innerWidth / 2.0 / BC_CAMERA.zoom) - BC_CAMERA.position.x) * BC_CAMERA.zoom),
|
||||||
Math.floor(((window.innerHeight / 2.0 / BC_CAMERA.zoom) - BC_CAMERA.position.y) * BC_CAMERA.zoom)
|
Math.floor(((window.innerHeight / 2.0 / BC_CAMERA.zoom) - BC_CAMERA.position.y) * BC_CAMERA.zoom)
|
||||||
|
@ -23,6 +23,7 @@ import {
|
|||||||
import { handleBuildingsIncome, incBuildingCount } from "./Buildings/Buildings";
|
import { handleBuildingsIncome, incBuildingCount } from "./Buildings/Buildings";
|
||||||
import { handleDayNightCycle } from "./World/DayNightCycle";
|
import { handleDayNightCycle } from "./World/DayNightCycle";
|
||||||
import { ambientDay, ambientMusic, ambientNight, handleSounds } from "./Sound/Sound";
|
import { ambientDay, ambientMusic, ambientNight, handleSounds } from "./Sound/Sound";
|
||||||
|
import { handleChunkFilling } from "./WorldGeneration/ChunkFillQueue";
|
||||||
|
|
||||||
export function generateWorld() {
|
export function generateWorld() {
|
||||||
|
|
||||||
@ -34,12 +35,12 @@ function setupGlobalInput() {
|
|||||||
window.addEventListener("wheel", (event) => {
|
window.addEventListener("wheel", (event) => {
|
||||||
const delta = Math.sign(event.deltaY);
|
const delta = Math.sign(event.deltaY);
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
BC_CAMERA.zoom = Number(clampNumber(BC_CAMERA.zoom - 0.1, 0.6, 1.2).toFixed(2));
|
BC_CAMERA.targetZoom = Number(clampNumber(BC_CAMERA.targetZoom - BC_CAMERA.zoomStep, BC_CAMERA.minZoom, BC_CAMERA.maxZoom).toFixed(2));
|
||||||
} else {
|
} else {
|
||||||
BC_CAMERA.zoom = Number(clampNumber(BC_CAMERA.zoom + 0.1, 0.6, 1.2).toFixed(2));
|
BC_CAMERA.targetZoom = Number(clampNumber(BC_CAMERA.targetZoom + BC_CAMERA.zoomStep, BC_CAMERA.minZoom, BC_CAMERA.maxZoom).toFixed(2));
|
||||||
}
|
}
|
||||||
UICameraInfo.update((s) => {
|
UICameraInfo.update((s) => {
|
||||||
s.zoom = BC_CAMERA.zoom;
|
s.zoom = BC_CAMERA.targetZoom;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -223,6 +224,8 @@ export async function initGame() {
|
|||||||
await app.init({ resizeTo: window, antialias: false });
|
await app.init({ resizeTo: window, antialias: false });
|
||||||
document.body.appendChild(app.canvas);
|
document.body.appendChild(app.canvas);
|
||||||
setBC_APP(app);
|
setBC_APP(app);
|
||||||
|
app.ticker.targetFPMS = 0.14;
|
||||||
|
app.ticker.maxFPS = 140;
|
||||||
|
|
||||||
await loadGameAssets();
|
await loadGameAssets();
|
||||||
UIMainPipe.update((s) => {
|
UIMainPipe.update((s) => {
|
||||||
@ -249,6 +252,7 @@ export async function initGame() {
|
|||||||
app.ticker.add(inputControllerTick);
|
app.ticker.add(inputControllerTick);
|
||||||
app.ticker.add(calculateViewportFromCamera);
|
app.ticker.add(calculateViewportFromCamera);
|
||||||
app.ticker.add(updateChunksVisibility);
|
app.ticker.add(updateChunksVisibility);
|
||||||
|
app.ticker.add(handleChunkFilling);
|
||||||
app.ticker.add(profileFPS);
|
app.ticker.add(profileFPS);
|
||||||
app.ticker.add(handleBuildingsIncome);
|
app.ticker.add(handleBuildingsIncome);
|
||||||
|
|
||||||
|
@ -60,7 +60,11 @@ export let BC_CHUNKS_SETTINGS = {
|
|||||||
export const BC_CAMERA = {
|
export const BC_CAMERA = {
|
||||||
position: {x: 0.0, y: 0.0},
|
position: {x: 0.0, y: 0.0},
|
||||||
offset_position: {x: 0.0, y: 0.0},
|
offset_position: {x: 0.0, y: 0.0},
|
||||||
zoom: 1.0
|
zoom: 1.0,
|
||||||
|
targetZoom: 1.0,
|
||||||
|
minZoom: 0.25,
|
||||||
|
maxZoom: 1.2,
|
||||||
|
zoomStep: 0.05,
|
||||||
};
|
};
|
||||||
|
|
||||||
export let PRNG = new Alea();
|
export let PRNG = new Alea();
|
||||||
|
@ -75,6 +75,13 @@ export function interpolate(x, y, a) {
|
|||||||
return x * (1 - a) + y * a;
|
return x * (1 - a) + y * a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* careful with delta time! it can be laggy
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
* @param {Number} a
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function interpolateCos(x, y, a) {
|
export function interpolateCos(x, y, a) {
|
||||||
let m = (1-Math.cos(a*Math.PI))/2;
|
let m = (1-Math.cos(a*Math.PI))/2;
|
||||||
return (x*(1-m)+y*m);
|
return (x*(1-m)+y*m);
|
||||||
|
@ -21,13 +21,14 @@ let dayColorsCue = new RGBCue(
|
|||||||
[
|
[
|
||||||
new RGBColor(1, 22, 46),
|
new RGBColor(1, 22, 46),
|
||||||
new RGBColor(1, 66, 109),
|
new RGBColor(1, 66, 109),
|
||||||
|
new RGBColor(230, 109, 109),
|
||||||
new RGBColor(255, 255, 255),
|
new RGBColor(255, 255, 255),
|
||||||
new RGBColor(255, 255, 192),
|
new RGBColor(255, 255, 192),
|
||||||
new RGBColor(136, 99, 77),
|
new RGBColor(230, 134, 77),
|
||||||
new RGBColor(1, 66, 109),
|
new RGBColor(1, 66, 109),
|
||||||
new RGBColor(1, 22, 46),
|
new RGBColor(1, 22, 46),
|
||||||
],
|
],
|
||||||
[0.0, 0.15, 0.4, 0.75, 0.8, 0.9, 1.0],
|
[0.0, 0.15, 0.2, 0.4, 0.8, 0.85, 0.9, 1.0],
|
||||||
"cos"
|
"cos"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
24
src/Game/WorldGeneration/ChunkFillQueue.js
Normal file
24
src/Game/WorldGeneration/ChunkFillQueue.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { WorldChunk } from "../WorldChunk/WorldChunk";
|
||||||
|
import { fillChunk } from "./WorldGeneration";
|
||||||
|
|
||||||
|
let chunkFillQueue = [];
|
||||||
|
let currentChunkIndex = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {WorldChunk} chunk
|
||||||
|
*/
|
||||||
|
export function addChunkToFillQueue(chunk, x, y)
|
||||||
|
{
|
||||||
|
chunkFillQueue.push({chunk, x, y});
|
||||||
|
currentChunkIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handleChunkFilling(tick) {
|
||||||
|
// console.log(tick.deltaMS);
|
||||||
|
if(currentChunkIndex < 0) return;
|
||||||
|
fillChunk(chunkFillQueue[currentChunkIndex].chunk, chunkFillQueue[currentChunkIndex].x, chunkFillQueue[currentChunkIndex].y);
|
||||||
|
chunkFillQueue.pop();
|
||||||
|
currentChunkIndex--;
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
import { Noise } from "noisejs";
|
import { Noise } from "noisejs";
|
||||||
import { BC_CAMERA, BC_CHUNKS_SETTINGS, BC_SPRITES_SETTINGS, BC_TERRAIN_SETTINGS, PRNG } from "../GlobalVariables/GlobalVariables";
|
import { BC_CAMERA, BC_CHUNKS_SETTINGS, BC_SPRITES_SETTINGS, BC_TERRAIN_SETTINGS, PRNG } from "../GlobalVariables/GlobalVariables";
|
||||||
import { integerDivision } from "../Utils/Math.utils";
|
import { clampNumber, integerDivision, mapRange } from "../Utils/Math.utils";
|
||||||
import { addToViewport } from "../Utils/World.utils";
|
import { addToViewport } from "../Utils/World.utils";
|
||||||
import { WorldChunk, createWorldChunkContainer } from "../WorldChunk/WorldChunk";
|
import { WorldChunk, createWorldChunkContainer } from "../WorldChunk/WorldChunk";
|
||||||
import { getSpriteFromAtlas } from "../Utils/Sprites.utils";
|
import { getSpriteFromAtlas } from "../Utils/Sprites.utils";
|
||||||
import * as PIXI from "../../pixi/pixi.mjs";
|
import * as PIXI from "../../pixi/pixi.mjs";
|
||||||
import { BuildingsObjectProps, TerrainObjectProps, VegetationObjectProps, VisibleChunkProps } from "./ObjectsPropsSchemes";
|
import { BuildingsObjectProps, TerrainObjectProps, VegetationObjectProps, VisibleChunkProps } from "./ObjectsPropsSchemes";
|
||||||
import { Vault } from "../Utils/DataTypes.utils";
|
import { NumberCue, RGBColor, Vault } from "../Utils/DataTypes.utils";
|
||||||
|
import { addChunkToFillQueue } from "./ChunkFillQueue";
|
||||||
// import {WorldChunk} from "../Types/WorldGenerationTypes";
|
// import {WorldChunk} from "../Types/WorldGenerationTypes";
|
||||||
|
|
||||||
const terrainSpriteList = {
|
const terrainSpriteList = {
|
||||||
@ -152,8 +153,8 @@ export function updateChunksVisibility() {
|
|||||||
vis_chunk.chunkRef.chunk.visible = false;
|
vis_chunk.chunkRef.chunk.visible = false;
|
||||||
});
|
});
|
||||||
VISIBLE_CHUNKS.clear();
|
VISIBLE_CHUNKS.clear();
|
||||||
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 t_chunkId = cx + i + "_" + (cy + j);
|
let t_chunkId = cx + i + "_" + (cy + j);
|
||||||
if (WORLD_CHUNKS.existsKey(t_chunkId)) {
|
if (WORLD_CHUNKS.existsKey(t_chunkId)) {
|
||||||
VISIBLE_CHUNKS.set(t_chunkId, new VisibleChunkProps(WORLD_CHUNKS.get(t_chunkId), i === 0 && j === 0));
|
VISIBLE_CHUNKS.set(t_chunkId, new VisibleChunkProps(WORLD_CHUNKS.get(t_chunkId), i === 0 && j === 0));
|
||||||
@ -173,7 +174,8 @@ export function updateChunksVisibility() {
|
|||||||
new Vault("vegetation"),
|
new Vault("vegetation"),
|
||||||
new Vault("buildings")
|
new Vault("buildings")
|
||||||
);
|
);
|
||||||
fillChunk(chunk0, cx + i, cy + j);
|
// fillChunk(chunk0, cx + i, cy + j);
|
||||||
|
addChunkToFillQueue(chunk0, cx + i, cy + j);
|
||||||
WORLD_CHUNKS.set(t_chunkId, chunk0);
|
WORLD_CHUNKS.set(t_chunkId, chunk0);
|
||||||
addToViewport(newChunk);
|
addToViewport(newChunk);
|
||||||
VISIBLE_CHUNKS.set(t_chunkId, new VisibleChunkProps(WORLD_CHUNKS.get(t_chunkId), i === 0 && j === 0));
|
VISIBLE_CHUNKS.set(t_chunkId, new VisibleChunkProps(WORLD_CHUNKS.get(t_chunkId), i === 0 && j === 0));
|
||||||
@ -357,24 +359,52 @@ export function createFirstWorldChunks() {
|
|||||||
enableAutoGeneration = true;
|
enableAutoGeneration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let noise = new Noise(Math.floor(PRNG() * 18882232));
|
let noise = new Noise(Math.floor(PRNG() * 188822321));
|
||||||
|
let noiseErosion = new Noise(Math.floor(PRNG() * 327749029));
|
||||||
|
let noiseBiomes = new Noise(Math.floor(PRNG() * 927472011));
|
||||||
|
|
||||||
function fillChunk(chunk, x, y) {
|
let terrainCue = new NumberCue([0, 1, 2, 3, 3], [0.0, 0.45, 0.5, 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]);
|
||||||
|
|
||||||
|
export function fillChunk(chunk, x, y) {
|
||||||
let ii = 0;
|
let ii = 0;
|
||||||
let jj = 0;
|
let jj = 0;
|
||||||
for (let i = BC_CHUNKS_SETTINGS.width * x; i < BC_CHUNKS_SETTINGS.width * (x + 1); i++) {
|
for (let i = BC_CHUNKS_SETTINGS.width * x; i < BC_CHUNKS_SETTINGS.width * (x + 1); i++) {
|
||||||
jj = 0;
|
jj = 0;
|
||||||
for (let j = BC_CHUNKS_SETTINGS.height * y; j < BC_CHUNKS_SETTINGS.height * (y + 1); j++) {
|
for (let j = BC_CHUNKS_SETTINGS.height * y; j < BC_CHUNKS_SETTINGS.height * (y + 1); j++) {
|
||||||
let res = (noise.simplex2(i * 0.04, j * 0.04) + 1) / 2;
|
let res = (noise.simplex2(i * 0.025, j * 0.025) + 1) / 2;
|
||||||
|
let resR = (noiseErosion.simplex2(i * 0.3, j * 0.3) + 1) / 2;
|
||||||
|
let resB = (noiseBiomes.simplex2(i * 0.01, j * 0.01) + 1) / 2;
|
||||||
|
if (resB > 0.7) {
|
||||||
|
res = clampNumber(res - resR / 4, 0.0, 0.99);
|
||||||
|
}
|
||||||
|
if (resB > 0.5 && res < 0.9 && res >= 0.5) {
|
||||||
|
res = clampNumber(res + resR / 4, 0.0, 0.99);
|
||||||
|
}
|
||||||
|
// res = Math.pow(res, 2);
|
||||||
|
// console.log(resR);
|
||||||
|
// let resB = (noiseBiomes.perlin2(i * 0.01, j * 0.01) + 1) / 2;
|
||||||
|
// console.log(Math.pow(resB, 0.5));
|
||||||
// console.log(res);
|
// console.log(res);
|
||||||
res = Math.pow(res, 1.2);
|
// res = clampNumber(res * resB, 0.0, 0.99);
|
||||||
res = Math.floor(res * 4);
|
// if(resB < 0.5)
|
||||||
|
// {
|
||||||
|
// res = clampNumber(res / 2 , 0.0, 0.99);
|
||||||
|
// }
|
||||||
|
// else if(resB < 0.9)
|
||||||
|
// {
|
||||||
|
// res = clampNumber(res * 2, 0.0, 0.99);
|
||||||
|
// }
|
||||||
|
// res = Math.pow(res, 0.9);
|
||||||
|
let sTint = new RGBColor(255, 255, 255).multiplyByNumber(terrainTintCue.getValueAt(res)).toNumber();
|
||||||
|
res = Math.floor(terrainCue.getValueAt(res));
|
||||||
let sprite = getSpriteFromAtlas(
|
let sprite = getSpriteFromAtlas(
|
||||||
"assets/images/world/world_terrain_atlas.png",
|
"assets/images/world/world_terrain_atlas.png",
|
||||||
new PIXI.Rectangle(16 * terrainSpriteList[res].x, 16 * terrainSpriteList[res].y, 16, 16)
|
new PIXI.Rectangle(16 * terrainSpriteList[res].x, 16 * terrainSpriteList[res].y, 16, 16)
|
||||||
);
|
);
|
||||||
sprite.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
sprite.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
||||||
sprite.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
sprite.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
||||||
|
sprite.tint = sTint;
|
||||||
addToTerrain(chunk, sprite, { type: terrainTypeList[res] }, i, j);
|
addToTerrain(chunk, sprite, { type: terrainTypeList[res] }, i, j);
|
||||||
// console.log(ii, jj);
|
// console.log(ii, jj);
|
||||||
// addToTerrain(sprite, {x: i, y: j}, {type: terrainTypeList[res]});
|
// addToTerrain(sprite, {x: i, y: j}, {type: terrainTypeList[res]});
|
||||||
@ -387,6 +417,7 @@ function fillChunk(chunk, x, y) {
|
|||||||
);
|
);
|
||||||
veg.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
veg.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
||||||
veg.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
veg.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
||||||
|
veg.tint = sTint;
|
||||||
addToVegetation(chunk, veg, { ...grassVegResourcesList[rv] }, i, j);
|
addToVegetation(chunk, veg, { ...grassVegResourcesList[rv] }, i, j);
|
||||||
jj++;
|
jj++;
|
||||||
continue;
|
continue;
|
||||||
@ -400,6 +431,7 @@ function fillChunk(chunk, x, y) {
|
|||||||
);
|
);
|
||||||
veg.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
veg.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
||||||
veg.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
veg.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
||||||
|
veg.tint = sTint;
|
||||||
addToVegetation(chunk, veg, { ...sandVegResourcesList[rv] }, i, j);
|
addToVegetation(chunk, veg, { ...sandVegResourcesList[rv] }, i, j);
|
||||||
jj++;
|
jj++;
|
||||||
continue;
|
continue;
|
||||||
@ -413,6 +445,7 @@ function fillChunk(chunk, x, y) {
|
|||||||
);
|
);
|
||||||
veg.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
veg.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
||||||
veg.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
veg.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
||||||
|
veg.tint = sTint;
|
||||||
addToVegetation(chunk, veg, { ...stoneVegResourcesList[rv] }, i, j);
|
addToVegetation(chunk, veg, { ...stoneVegResourcesList[rv] }, i, j);
|
||||||
jj++;
|
jj++;
|
||||||
continue;
|
continue;
|
||||||
|
135
src/Test.js
Normal file
135
src/Test.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
let cols = 5; //columns in the grid
|
||||||
|
let rows = 5; //rows in the grid
|
||||||
|
|
||||||
|
let grid = new Array(cols); //array of all the grid points
|
||||||
|
|
||||||
|
let openSet = []; //array containing unevaluated grid points
|
||||||
|
let closedSet = []; //array containing completely evaluated grid points
|
||||||
|
|
||||||
|
let start; //starting grid point
|
||||||
|
let end; // ending grid point (goal)
|
||||||
|
let path = [];
|
||||||
|
|
||||||
|
//heuristic we will be using - Manhattan distance
|
||||||
|
//for other heuristics visit - https://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
|
||||||
|
function heuristic(position0, position1) {
|
||||||
|
let d1 = Math.abs(position1.x - position0.x);
|
||||||
|
let d2 = Math.abs(position1.y - position0.y);
|
||||||
|
|
||||||
|
return d1 + d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//constructor function to create all the grid points as objects containind the data for the points
|
||||||
|
function GridPoint(x, y) {
|
||||||
|
this.x = x; //x location of the grid point
|
||||||
|
this.y = y; //y location of the grid point
|
||||||
|
this.f = 0; //total cost function
|
||||||
|
this.g = 0; //cost function from start to the current grid point
|
||||||
|
this.h = 0; //heuristic estimated cost function from current grid point to the goal
|
||||||
|
this.neighbors = []; // neighbors of the current grid point
|
||||||
|
this.parent = undefined; // immediate source of the current grid point
|
||||||
|
|
||||||
|
// update neighbors array for a given grid point
|
||||||
|
this.updateNeighbors = function (grid) {
|
||||||
|
let i = this.x;
|
||||||
|
let j = this.y;
|
||||||
|
if (i < cols - 1) {
|
||||||
|
this.neighbors.push(grid[i + 1][j]);
|
||||||
|
}
|
||||||
|
if (i > 0) {
|
||||||
|
this.neighbors.push(grid[i - 1][j]);
|
||||||
|
}
|
||||||
|
if (j < rows - 1) {
|
||||||
|
this.neighbors.push(grid[i][j + 1]);
|
||||||
|
}
|
||||||
|
if (j > 0) {
|
||||||
|
this.neighbors.push(grid[i][j - 1]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//initializing the grid
|
||||||
|
function init() {
|
||||||
|
//making a 2D array
|
||||||
|
for (let i = 0; i < cols; i++) {
|
||||||
|
grid[i] = new Array(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < cols; i++) {
|
||||||
|
for (let j = 0; j < rows; j++) {
|
||||||
|
grid[i][j] = new GridPoint(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < cols; i++) {
|
||||||
|
for (let j = 0; j < rows; j++) {
|
||||||
|
grid[i][j].updateNeighbors(grid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start = grid[0][0];
|
||||||
|
end = grid[cols - 1][rows - 1];
|
||||||
|
|
||||||
|
openSet.push(start);
|
||||||
|
|
||||||
|
console.log(grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
//A star search implementation
|
||||||
|
|
||||||
|
export function search() {
|
||||||
|
init();
|
||||||
|
while (openSet.length > 0) {
|
||||||
|
//assumption lowest index is the first one to begin with
|
||||||
|
let lowestIndex = 0;
|
||||||
|
for (let i = 0; i < openSet.length; i++) {
|
||||||
|
if (openSet[i].f < openSet[lowestIndex].f) {
|
||||||
|
lowestIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let current = openSet[lowestIndex];
|
||||||
|
|
||||||
|
if (current === end) {
|
||||||
|
let temp = current;
|
||||||
|
path.push(temp);
|
||||||
|
while (temp.parent) {
|
||||||
|
path.push(temp.parent);
|
||||||
|
temp = temp.parent;
|
||||||
|
}
|
||||||
|
console.log("DONE!");
|
||||||
|
// return the traced path
|
||||||
|
return path.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove current from openSet
|
||||||
|
openSet.splice(lowestIndex, 1);
|
||||||
|
//add current to closedSet
|
||||||
|
closedSet.push(current);
|
||||||
|
|
||||||
|
let neighbors = current.neighbors;
|
||||||
|
|
||||||
|
for (let i = 0; i < neighbors.length; i++) {
|
||||||
|
let neighbor = neighbors[i];
|
||||||
|
|
||||||
|
if (!closedSet.includes(neighbor)) {
|
||||||
|
let possibleG = current.g + 1;
|
||||||
|
|
||||||
|
if (!openSet.includes(neighbor)) {
|
||||||
|
openSet.push(neighbor);
|
||||||
|
} else if (possibleG >= neighbor.g) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
neighbor.g = possibleG;
|
||||||
|
neighbor.h = heuristic(neighbor, end);
|
||||||
|
neighbor.f = neighbor.g + neighbor.h;
|
||||||
|
neighbor.parent = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//no solution by default
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(search());
|
Loading…
x
Reference in New Issue
Block a user