diff --git a/src/App.svelte b/src/App.svelte
index cab2516..0e323a6 100644
--- a/src/App.svelte
+++ b/src/App.svelte
@@ -74,6 +74,9 @@
ambientSound = s.ambient;
musicSound = s.music;
});
+
+ import {search} from "./Test";
+ search();
diff --git a/src/Game/Camera/Camera.js b/src/Game/Camera/Camera.js
index 14766f0..a00c33e 100644
--- a/src/Game/Camera/Camera.js
+++ b/src/Game/Camera/Camera.js
@@ -1,5 +1,6 @@
import { BC_CAMERA, BC_VIEWPORT } from "../GlobalVariables/GlobalVariables";
import { UICameraInfo } from "../UIPipes/UIPipes";
+import { interpolate, interpolateCos } from "../Utils/Math.utils";
export function moveVertically(tick, keyCode) {
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_CAMERA.zoom = interpolate(BC_CAMERA.zoom, BC_CAMERA.targetZoom, (tick.deltaMS / 1000) * 45);
BC_VIEWPORT.position.set(
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)
diff --git a/src/Game/Game.js b/src/Game/Game.js
index 0389366..bdd317f 100644
--- a/src/Game/Game.js
+++ b/src/Game/Game.js
@@ -23,6 +23,7 @@ import {
import { handleBuildingsIncome, incBuildingCount } from "./Buildings/Buildings";
import { handleDayNightCycle } from "./World/DayNightCycle";
import { ambientDay, ambientMusic, ambientNight, handleSounds } from "./Sound/Sound";
+import { handleChunkFilling } from "./WorldGeneration/ChunkFillQueue";
export function generateWorld() {
@@ -34,12 +35,12 @@ function setupGlobalInput() {
window.addEventListener("wheel", (event) => {
const delta = Math.sign(event.deltaY);
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 {
- 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) => {
- 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 });
document.body.appendChild(app.canvas);
setBC_APP(app);
+ app.ticker.targetFPMS = 0.14;
+ app.ticker.maxFPS = 140;
await loadGameAssets();
UIMainPipe.update((s) => {
@@ -249,6 +252,7 @@ export async function initGame() {
app.ticker.add(inputControllerTick);
app.ticker.add(calculateViewportFromCamera);
app.ticker.add(updateChunksVisibility);
+ app.ticker.add(handleChunkFilling);
app.ticker.add(profileFPS);
app.ticker.add(handleBuildingsIncome);
diff --git a/src/Game/GlobalVariables/GlobalVariables.js b/src/Game/GlobalVariables/GlobalVariables.js
index 8cb55ec..ddb9fd8 100644
--- a/src/Game/GlobalVariables/GlobalVariables.js
+++ b/src/Game/GlobalVariables/GlobalVariables.js
@@ -60,7 +60,11 @@ export let BC_CHUNKS_SETTINGS = {
export const BC_CAMERA = {
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();
diff --git a/src/Game/Utils/Math.utils.js b/src/Game/Utils/Math.utils.js
index 907732e..a6839b1 100644
--- a/src/Game/Utils/Math.utils.js
+++ b/src/Game/Utils/Math.utils.js
@@ -75,6 +75,13 @@ export function interpolate(x, 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) {
let m = (1-Math.cos(a*Math.PI))/2;
return (x*(1-m)+y*m);
diff --git a/src/Game/World/DayNightCycle.js b/src/Game/World/DayNightCycle.js
index 5957703..ced6283 100644
--- a/src/Game/World/DayNightCycle.js
+++ b/src/Game/World/DayNightCycle.js
@@ -21,13 +21,14 @@ let dayColorsCue = new RGBCue(
[
new RGBColor(1, 22, 46),
new RGBColor(1, 66, 109),
+ new RGBColor(230, 109, 109),
new RGBColor(255, 255, 255),
new RGBColor(255, 255, 192),
- new RGBColor(136, 99, 77),
+ new RGBColor(230, 134, 77),
new RGBColor(1, 66, 109),
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"
);
diff --git a/src/Game/WorldGeneration/ChunkFillQueue.js b/src/Game/WorldGeneration/ChunkFillQueue.js
new file mode 100644
index 0000000..db1ae04
--- /dev/null
+++ b/src/Game/WorldGeneration/ChunkFillQueue.js
@@ -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--;
+
+}
diff --git a/src/Game/WorldGeneration/WorldGeneration.js b/src/Game/WorldGeneration/WorldGeneration.js
index 3350b09..5c29149 100644
--- a/src/Game/WorldGeneration/WorldGeneration.js
+++ b/src/Game/WorldGeneration/WorldGeneration.js
@@ -1,12 +1,13 @@
import { Noise } from "noisejs";
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 { WorldChunk, createWorldChunkContainer } from "../WorldChunk/WorldChunk";
import { getSpriteFromAtlas } from "../Utils/Sprites.utils";
import * as PIXI from "../../pixi/pixi.mjs";
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";
const terrainSpriteList = {
@@ -152,8 +153,8 @@ export function updateChunksVisibility() {
vis_chunk.chunkRef.chunk.visible = false;
});
VISIBLE_CHUNKS.clear();
- for (let i = -1; i < 2; i++) {
- for (let j = -1; j < 2; j++) {
+ for (let i = -2; i < 3; i++) {
+ for (let j = -2; j < 3; j++) {
let t_chunkId = cx + i + "_" + (cy + j);
if (WORLD_CHUNKS.existsKey(t_chunkId)) {
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("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);
addToViewport(newChunk);
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;
}
-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 jj = 0;
for (let i = BC_CHUNKS_SETTINGS.width * x; i < BC_CHUNKS_SETTINGS.width * (x + 1); i++) {
jj = 0;
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);
- res = Math.pow(res, 1.2);
- res = Math.floor(res * 4);
+ // res = clampNumber(res * resB, 0.0, 0.99);
+ // 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(
"assets/images/world/world_terrain_atlas.png",
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.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
+ sprite.tint = sTint;
addToTerrain(chunk, sprite, { type: terrainTypeList[res] }, i, j);
// console.log(ii, jj);
// 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.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
+ veg.tint = sTint;
addToVegetation(chunk, veg, { ...grassVegResourcesList[rv] }, i, j);
jj++;
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.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
+ veg.tint = sTint;
addToVegetation(chunk, veg, { ...sandVegResourcesList[rv] }, i, j);
jj++;
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.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
+ veg.tint = sTint;
addToVegetation(chunk, veg, { ...stoneVegResourcesList[rv] }, i, j);
jj++;
continue;
diff --git a/src/Test.js b/src/Test.js
new file mode 100644
index 0000000..e3a2fed
--- /dev/null
+++ b/src/Test.js
@@ -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());
\ No newline at end of file