fixed day-night cycle colors and changed world generation

This commit is contained in:
TorgaW 2024-04-11 02:49:14 +03:00
parent 78686fd323
commit b4c6b97ca4
9 changed files with 230 additions and 17 deletions

View File

@ -74,6 +74,9 @@
ambientSound = s.ambient;
musicSound = s.music;
});
import {search} from "./Test";
search();
</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">

View File

@ -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)

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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"
);

View 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--;
}

View File

@ -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;

135
src/Test.js Normal file
View 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());