diff --git a/public/assets/images/world/world_terrain_atlas_overlay.png b/public/assets/images/world/world_terrain_atlas_overlay.png index 4555e4a..c871e16 100644 Binary files a/public/assets/images/world/world_terrain_atlas_overlay.png and b/public/assets/images/world/world_terrain_atlas_overlay.png differ diff --git a/src/Game/Camera/Camera.js b/src/Game/Camera/Camera.js index fe7467c..405bed3 100644 --- a/src/Game/Camera/Camera.js +++ b/src/Game/Camera/Camera.js @@ -2,15 +2,17 @@ import { BC_CAMERA, BC_VIEWPORT } from "../GlobalVariables/GlobalVariables"; import { UICameraInfo } from "../UIPipes/UIPipes"; import { interpolate, interpolateCos } from "../Utils/Math.utils"; +const cameraSpeed = 500; + export function moveVertically(tick, keyCode) { - BC_CAMERA.position.y += (tick.deltaMS / 1000) * 1800 * (keyCode === "KeyS" ? 1 : -1); + BC_CAMERA.position.y += (tick.deltaMS / 1000) * cameraSpeed * (keyCode === "KeyS" ? 1 : -1); UICameraInfo.update((s) => { s.position.y = BC_CAMERA.position.y; }); } export function moveHorizontally(tick, keyCode) { - BC_CAMERA.position.x += (tick.deltaMS / 1000) * 1800 * (keyCode === "KeyD" ? 1 : -1); + BC_CAMERA.position.x += (tick.deltaMS / 1000) * cameraSpeed * (keyCode === "KeyD" ? 1 : -1); UICameraInfo.update((s) => { s.position.x = BC_CAMERA.position.x; }); diff --git a/src/Game/Game.js b/src/Game/Game.js index 97323c0..467d57c 100644 --- a/src/Game/Game.js +++ b/src/Game/Game.js @@ -4,7 +4,7 @@ import { UICameraInfo, UIGameProfilerPipe, UIMainPipe, UIObtainedResourcesPipe, import { getSpriteFromAtlas } from "./Utils/Sprites.utils"; import { profileFPS } from "./Profiler/Profiler"; import { createKeyboardBinding, inputControllerTick } from "./InputController/InputController"; -import { BC_APP, BC_BUILDING_PLACEHOLDERS, BC_CAMERA, BC_CURRENT_SCENE, BC_SPRITES_SETTINGS, BC_VIEWPORT, BC_WORLD, PRNG, setBC_APP, setBC_CURRENT_SCENE, setBC_NPC_LAYER, setBC_SELECTION, setBC_VIEWPORT, setBC_WORLD } from "./GlobalVariables/GlobalVariables"; +import { BC_APP, BC_BUILDING_PLACEHOLDERS, BC_CAMERA, BC_CURRENT_SCENE, BC_SPRITES_SETTINGS, BC_TERRAIN_MANAGER, BC_VIEWPORT, BC_WORLD, PRNG, setBC_APP, setBC_CURRENT_SCENE, setBC_NPC_LAYER, setBC_SELECTION, setBC_TERRAIN_MANAGER, setBC_VIEWPORT, setBC_WORLD } from "./GlobalVariables/GlobalVariables"; import { Point2D, PointInt2D, clampNumber, interpolate, } from "./Utils/Math.utils"; import { calculateViewportFromCamera, moveHorizontally, moveVertically, screenToWorldCoordinates } from "./Camera/Camera"; @@ -14,13 +14,15 @@ import { ambientDay, ambientMusic, ambientNight, handleSounds } from "./Sound/So import { addGameObjectToGameState, gameStateObjectsCleaner } from "./GameState/GameState"; import { tickHandler } from "./TickHandler/TickHandler"; import { GameScene } from "./GameScene/GameScene"; -import { createFirstWorldChunks, getTileAt, getWorldChunkAt, worldCoordinatesToChunkIndex } from "./WorldGeneration/WorldGen"; -import { ChunkStorageTypes } from "./WorldGeneration/WorldChunk/WorldGenChunk"; -import { WorldChunksVisibilityUpdater } from "./WorldGeneration/WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater"; +// import { createFirstWorldChunks, getTileAt, getWorldChunkAt, worldCoordinatesToChunkIndex } from "./WorldGeneration/WorldGen_"; +// import { ChunkStorageTypes } from "./WorldGeneration/WorldChunk/WorldGenChunk"; +// import { WorldChunksVisibilityUpdater } from "./WorldGeneration/WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater"; import { NPCProto } from "./NPC/NPCProto/NPCProto"; import { NPCController } from "./NPC/NPCController/NPCController"; import { PathFinder } from "./Utils/PathFinding.utils"; import { getNavigationGridTile } from "./World/NavigationGrid/NavigationGrid"; +import { TerrainManger } from "./WorldGenV2/TerrainManager/TerrainManager"; +import { generateFirstChunks } from "./WorldGenV2/WorldGenV2"; export function generateWorld() { @@ -55,12 +57,19 @@ function setupInGameSelector() { let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y); // let tChunk = getWorldChunkAt(t.x, t.y); // let tTerrainTile = tChunk.getFromChunk(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN); - let terrainTile = getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN); + // let terrainTile = getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN); // console.log(terrainTile); - UISelectionInfo.update((s)=>{ - s.types = [terrainTile.props.type]; - }); - + // UISelectionInfo.update((s)=>{ + // s.types = [terrainTile.props.type]; + // }); + let tile = BC_TERRAIN_MANAGER.getTileAt(new PointInt2D(t.x, t.y)); + // console.log(tile); + if(tile) + { + UISelectionInfo.update((s)=>{ + s.types = [tile.tileId]; + }); + } t.x = BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale * Math.floor(t.x / (BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale)); t.y = BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale * Math.floor(t.y / (BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale)); sprite0.position.set(t.x, t.y); @@ -122,11 +131,11 @@ export async function initGame() { app.ticker.add(inputControllerTick); app.ticker.add(calculateViewportFromCamera); //static functions shitty binding - app.ticker.add(WorldChunksVisibilityUpdater.handleWorldChunksVisibility.bind(WorldChunksVisibilityUpdater)); - app.ticker.add(WorldChunksVisibilityUpdater.handleWorldChunkFilling.bind(WorldChunksVisibilityUpdater)); + // app.ticker.add(WorldChunksVisibilityUpdater.handleWorldChunksVisibility.bind(WorldChunksVisibilityUpdater)); + // app.ticker.add(WorldChunksVisibilityUpdater.handleWorldChunkFilling.bind(WorldChunksVisibilityUpdater)); //end of shit app.ticker.add(profileFPS); - app.ticker.add(handleBuildingsIncome); + // app.ticker.add(handleBuildingsIncome); createKeyboardBinding("KeyW", "Hold", [moveVertically]); createKeyboardBinding("KeyS", "Hold", [moveVertically]); @@ -147,8 +156,14 @@ function startGame() { ambientMusic.play(); BC_APP.ticker.add(gameStateObjectsCleaner); BC_APP.ticker.add(tickHandler); - - createFirstWorldChunks(); + + let terrainManager = new TerrainManger(); + terrainManager.currentTerrain = terrainManager.createNewTerrain(); + setBC_TERRAIN_MANAGER(terrainManager); + BC_VIEWPORT.addChild(terrainManager.currentTerrain.drawObject); + BC_APP.ticker.add(terrainManager.tickHandler.bind(terrainManager)); + generateFirstChunks(); + // createFirstWorldChunks(); let testNPCController = new NPCController(true); let testNPC = new NPCProto(true, testNPCController); diff --git a/src/Game/GameObject/GameObject.js b/src/Game/GameObject/GameObject.js index 36bdb9f..23338a1 100644 --- a/src/Game/GameObject/GameObject.js +++ b/src/Game/GameObject/GameObject.js @@ -66,4 +66,16 @@ export class GameObject { isTickEnabled(){return this._tickEnabled;}; isMarkedPendingKill(){return this._markedPendingKill;}; + isInitialized(){return (this.minorId > -1 && this.majorId > -1);}; + /** + * + * @param {GameObject} objectA + * @param {GameObject} objectB + * @returns + */ + static isEqual(objectA, objectB) + { + if(!objectA || !objectB) return false; + return (objectA.minorId === objectB.minorId) && (objectA.majorId === objectB.majorId); + }; }; \ No newline at end of file diff --git a/src/Game/GlobalVariables/GlobalVariables.js b/src/Game/GlobalVariables/GlobalVariables.js index 415b6d3..45ca036 100644 --- a/src/Game/GlobalVariables/GlobalVariables.js +++ b/src/Game/GlobalVariables/GlobalVariables.js @@ -1,6 +1,7 @@ import Alea from "alea"; import { Container } from "../../pixi/pixi.mjs"; import { GameScene } from "../GameScene/GameScene"; +import { TerrainManger } from "../WorldGenV2/TerrainManager/TerrainManager"; export let BC_APP; @@ -43,8 +44,8 @@ export function setBC_NPC_LAYER(npc_layer) { // export let BC_TERRAIN; export let BC_TERRAIN_SETTINGS = { tileSize: 16, - scale: 8.0, - totalSize: 16*8.0 + scale: 2, + totalSize: 16*2 } // export let BC_TERRAIN_VAULT = {}; // export function setBC_TERRAIN(terrain) { @@ -59,7 +60,7 @@ export let BC_TERRAIN_SETTINGS = { export let BC_SPRITES_SETTINGS = { defaultSize: 16, - scale: 8.0 + scale: 2 }; // export let BC_CHUNKS_VAULT = {}; @@ -71,11 +72,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, - targetZoom: 1.0, - minZoom: 0.25, - maxZoom: 1.2, - zoomStep: 0.05, + zoom: 1.5, + targetZoom: 1.5, + minZoom: 1.2, + maxZoom: 4, + zoomStep: 0.1, }; export let PRNG = new Alea(); @@ -95,4 +96,17 @@ export let BC_CURRENT_SCENE; */ export function setBC_CURRENT_SCENE(scene) { BC_CURRENT_SCENE = scene; -}; \ No newline at end of file +}; + +/** + * @type {TerrainManger} + */ +export let BC_TERRAIN_MANAGER; + +/** + * + * @param {TerrainManger} manager + */ +export function setBC_TERRAIN_MANAGER(manager) { + BC_TERRAIN_MANAGER = manager; +} \ No newline at end of file diff --git a/src/Game/SceneObjects/SceneObject.js b/src/Game/SceneObjects/SceneObject.js index d3790aa..7f210c8 100644 --- a/src/Game/SceneObjects/SceneObject.js +++ b/src/Game/SceneObjects/SceneObject.js @@ -1,6 +1,7 @@ import { GameObject } from "../GameObject/GameObject"; import { Container } from "../../pixi/pixi.mjs"; import { Point2D, PointInt2D } from "../Utils/Math.utils"; +import { addGameObjectToGameState } from "../GameState/GameState"; export class SceneObject extends GameObject { /** @@ -20,22 +21,33 @@ export class SceneObject extends GameObject { worldPosition = new PointInt2D(); /** - * - * @param {Boolean} tickAble + * + * @param {Boolean} tickAble */ - constructor(tickAble) - { + constructor(tickAble) { super(tickAble); // this._tickEnabled = tickAble; } + /** + * + * @param {SceneObject} childObject + */ + addChild(childObject) { + if (childObject.isMarkedPendingKill()) return; + if (childObject.isInitialized() === false) { + addGameObjectToGameState(childObject); + } + this.drawObject.addChild(childObject.drawObject); + childObject.onSpawn(); + } + /** * Instantly* kills drawObject (by PIXI) and after several ticks kills SceneObject - * + * * * not sure about instant killing */ - kill() - { + kill() { super.kill(); this.drawObject.destroy(); } diff --git a/src/Game/Utils/Math.utils.js b/src/Game/Utils/Math.utils.js index 98bac16..e860432 100644 --- a/src/Game/Utils/Math.utils.js +++ b/src/Game/Utils/Math.utils.js @@ -47,14 +47,14 @@ export class PointInt2D #x = 0; #y = 0; /** - * Point2D object + * PointInt2D object * @param {Number} x * @param {Number} y */ constructor(x = 0, y = 0) { - this.#x = x; - this.#y = y; + this.setX(x); + this.setY(y); } getX() { @@ -62,14 +62,8 @@ export class PointInt2D }; setX(x) { - if(x >= 0) - { - this.#x = Math.floor(x); - } - else - { - this.#x = Math.ceil(x); - } + this.#x = Math.trunc(x); + if(this.#x === -0) this.#x = 0; }; getY() { @@ -77,14 +71,8 @@ export class PointInt2D }; setY(y) { - if(y >= 0) - { - this.#y = Math.floor(y); - } - else - { - this.#y = Math.ceil(y); - } + this.#y = Math.trunc(y); + if(this.#y === -0) this.#y = 0; }; /** @@ -93,16 +81,10 @@ export class PointInt2D */ divideBy(x) { - if(x > 0) + 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); + this.#x = Math.trunc(this.#x / x); + this.#y = Math.trunc(this.#y / x); return true; } return false; @@ -110,16 +92,8 @@ export class PointInt2D multiplyBy(x) { - if(x >= 0) - { - this.#x = Math.floor(this.#x * x); - this.#y = Math.floor(this.#y * x); - } - else - { - this.#x = Math.ceil(this.#x * x); - this.#y = Math.ceil(this.#y * x); - } + this.#x = Math.trunc(this.#x * x); + this.#y = Math.trunc(this.#y * x); } /** diff --git a/src/Game/Utils/PRNG.utils.js b/src/Game/Utils/PRNG.utils.js index e69de29..3ba044b 100644 --- a/src/Game/Utils/PRNG.utils.js +++ b/src/Game/Utils/PRNG.utils.js @@ -0,0 +1,7 @@ +/** + * + * @param {Array} array + */ +export function selectRandomValueFromArray(array, ent) { + return array[(Math.floor(ent * 999999999999) % array.length)]; +} \ No newline at end of file diff --git a/src/Game/Utils/PathFinding.utils.js b/src/Game/Utils/PathFinding.utils.js index 7e277ab..9e2e3c0 100644 --- a/src/Game/Utils/PathFinding.utils.js +++ b/src/Game/Utils/PathFinding.utils.js @@ -1,10 +1,11 @@ import { BC_TERRAIN_SETTINGS } from "../GlobalVariables/GlobalVariables"; -import { ChunkStorageTypes } from "../WorldGeneration/WorldChunk/WorldGenChunk"; -import { getTileAt } from "../WorldGeneration/WorldGen"; +// import { ChunkStorageTypes } from "../WorldGeneration/WorldChunk/WorldGenChunk"; +// import { getTileAt } from "../WorldGeneration/WorldGen_"; import { PointInt2D } from "./Math.utils"; -import { SceneObject } from "../SceneObjects/SceneObject"; +// import { SceneObject } from "../SceneObjects/SceneObject"; import { getNavigationGridTile } from "../World/NavigationGrid/NavigationGrid"; -import { TerrainTile } from "../WorldGeneration/WorldObjects/TerrainTile/TerrainTile"; +import { TerrainTile } from "../WorldGenV2/Tiles/TerrainTile"; +// import { TerrainTile } from "../WorldGeneration/WorldObjects/TerrainTile/TerrainTile"; class PathFinderNode { position; diff --git a/src/Game/World/NavigationGrid/NavigationGrid.js b/src/Game/World/NavigationGrid/NavigationGrid.js index d33fd79..ac88d85 100644 --- a/src/Game/World/NavigationGrid/NavigationGrid.js +++ b/src/Game/World/NavigationGrid/NavigationGrid.js @@ -1,7 +1,9 @@ +import { BC_TERRAIN_MANAGER, BC_TERRAIN_SETTINGS } from "../../GlobalVariables/GlobalVariables"; import { PointInt2D } from "../../Utils/Math.utils"; import { PathFinder } from "../../Utils/PathFinding.utils"; -import { getWorldChunkAt, worldCoordinatesToChunkLocalCoordinates } from "../../WorldGeneration/WorldGen"; -import { TerrainTile } from "../../WorldGeneration/WorldObjects/TerrainTile/TerrainTile"; +import { TerrainTile } from "../../WorldGenV2/Tiles/TerrainTile"; +// import { getWorldChunkAt, worldCoordinatesToChunkLocalCoordinates } from "../../WorldGeneration/WorldGen"; +// import { TerrainTile } from "../../WorldGeneration/WorldObjects/TerrainTile/TerrainTile"; export class NavigationGridTile { @@ -59,8 +61,8 @@ export class NavigationGridChunk getFromChunk(xWorld, yWorld) { - let coords = worldCoordinatesToChunkLocalCoordinates(xWorld, yWorld); - return this._gridTiles.get(coords.x+"_"+coords.y); + let key = Math.floor(xWorld / BC_TERRAIN_SETTINGS.totalSize) * BC_TERRAIN_SETTINGS.totalSize + "_" + Math.floor(yWorld / BC_TERRAIN_SETTINGS.totalSize) * BC_TERRAIN_SETTINGS.totalSize; + return this._gridTiles.get(key); } /** @@ -107,10 +109,11 @@ export class NavigationGridChunk */ export function getNavigationGridTile(xWorld, yWorld) { - let chunk = getWorldChunkAt(xWorld, yWorld); + let chunk = BC_TERRAIN_MANAGER.getChunkAt(new PointInt2D(xWorld, yWorld)); + // console.log(chunk); if(chunk) { - return chunk.navigationGridChunk.getFromChunk(xWorld, yWorld); + return chunk.navigationChunk.getFromChunk(xWorld, yWorld); } return undefined; } diff --git a/src/Game/WorldGenV2/Chunk/Chunk.js b/src/Game/WorldGenV2/Chunk/Chunk.js new file mode 100644 index 0000000..2d1bb04 --- /dev/null +++ b/src/Game/WorldGenV2/Chunk/Chunk.js @@ -0,0 +1,63 @@ +import { GameObject } from "../../GameObject/GameObject"; +import { PointInt2D } from "../../Utils/Math.utils"; +import { NavigationGridChunk } from "../../World/NavigationGrid/NavigationGrid"; +import { TerrainTile } from "../Tiles/TerrainTile"; +import { Tile } from "../Tiles/Tile"; + +export const CHUNK_LAYER_TERRAIN = 0; + +export class Chunk extends GameObject +{ + /** + * @type {Map} + */ + terrainLayer = new Map(); + + chunkPivotCoordinates = new PointInt2D(); + + /** + * @type {NavigationGridChunk} + */ + navigationChunk = null; + + filled = false; + + /** + * + * @param {Boolean} tickable + * @param {PointInt2D} pivot + */ + constructor(tickable, pivot) + { + super(tickable); + this.chunkPivotCoordinates = pivot; + } + + /** + * + * @param {Number} layerId + * @param {Tile} object + */ + addToLayer(layerId, object) + { + switch (layerId) { + case CHUNK_LAYER_TERRAIN: + this.terrainLayer.set(object.tileKey, object); + break; + + default: + break; + } + } + + /** + * + * @param {Boolean} newVisibility + */ + changeVisibility(newVisibility) + { + for (const i of this.terrainLayer) { + i[1].drawObject.visible = newVisibility; + } + } +} \ No newline at end of file diff --git a/src/Game/WorldGenV2/Terrain/Generator/TerrainGenerator.js b/src/Game/WorldGenV2/Terrain/Generator/TerrainGenerator.js new file mode 100644 index 0000000..959cacd --- /dev/null +++ b/src/Game/WorldGenV2/Terrain/Generator/TerrainGenerator.js @@ -0,0 +1,55 @@ +import { Noise } from "noisejs"; +import { PRNG } from "../../../GlobalVariables/GlobalVariables"; +import { Point2D } from "../../../Utils/Math.utils"; +import { DWFBMSimplex2 } from "../../../Utils/Noise.utils"; +import { NumberCue } from "../../../Utils/DataTypes.utils"; + +export class TileValue { + noiseValue = -1; + temperatureValue = 0; + tileId = -1; + + constructor(noiseValue, tileId, temperatureValue) { + this.noiseValue = noiseValue; + this.tileId = tileId; + this.temperatureValue = temperatureValue; + } +} + +export class TerrainGenerator { + cNoise = new Noise(Math.floor(PRNG() * 999999999999)); + tNoise = new Noise(Math.floor(PRNG() * 999999999999)); + + /** + * + * @param {Noise} cNoise + * @param {Noise} tNoise + */ + constructor(cNoise, tNoise) { + if (cNoise) this.cNoise = cNoise; + if (tNoise) this.tNoise = tNoise; + } + + /** + * returns tile value at point + * @param {Point2D} point + * @returns {TileValue} + */ + getValueAt(point) { + let mainValue = DWFBMSimplex2(this.cNoise, point.getX() / 1000.0, point.getY() / 1000.0, 3.0); + mainValue *= mainValue; + mainValue *= DWFBMSimplex2(this.cNoise, point.getX() / 100, point.getY() / 100, 3.0); + let temperatureValue = DWFBMSimplex2(this.tNoise, point.getX() / 10.0, point.getY() / 10.0, 3.0); + // let tileId = -1; + // if (mainValue < 0.25) { + // tileId = 0; + // } else if (mainValue < 0.3) { + // tileId = 1; + // } else if (mainValue < 0.8) { + // tileId = 2; + // } else { + // tileId = 3; + // } + return new TileValue(mainValue, -1, temperatureValue); + } +} diff --git a/src/Game/WorldGenV2/Terrain/Terrain.js b/src/Game/WorldGenV2/Terrain/Terrain.js new file mode 100644 index 0000000..1675194 --- /dev/null +++ b/src/Game/WorldGenV2/Terrain/Terrain.js @@ -0,0 +1,77 @@ +import { Rectangle } from "../../../pixi/pixi.mjs"; +import { BC_CHUNKS_SETTINGS, BC_TERRAIN_SETTINGS } from "../../GlobalVariables/GlobalVariables"; +import { SceneObject } from "../../SceneObjects/SceneObject"; +import { Point2D, PointInt2D } from "../../Utils/Math.utils"; +import { NavigationGridTile } from "../../World/NavigationGrid/NavigationGrid"; +import { CHUNK_LAYER_TERRAIN, Chunk } from "../Chunk/Chunk"; +import { TerrainTile } from "../Tiles/TerrainTile"; +import { Tile } from "../Tiles/Tile"; +import { TerrainGenerator } from "./Generator/TerrainGenerator"; +import { createTerrainTileFromTileValue } from "./TerrainTilesFactory/TerrainTilesFactory"; + +export class Terrain extends SceneObject { + /** + * @type {Map} + */ + chunkStorage = new Map(); + /** + * @type {Map} + */ + visibleChunks = new Map(); + + terrainGenerator = new TerrainGenerator(); + + /** + * adds chunk to terrain. Chunk object must contain pivot coordinates + * @param {Chunk} chunk + */ + addChunk(chunk) { + this.chunkStorage.set(chunk.chunkPivotCoordinates.getX() + "_" + chunk.chunkPivotCoordinates.getY(), chunk); + } + + /** + * fills chunk with tiles + * @param {Chunk} chunk + */ + fillChunk(chunk) { + let ii = 0; + let jj = 0; + for (let i = BC_CHUNKS_SETTINGS.width * chunk.chunkPivotCoordinates.getX(); i < BC_CHUNKS_SETTINGS.width * (chunk.chunkPivotCoordinates.getX() + 1); i++) { + for (let j = BC_CHUNKS_SETTINGS.height * chunk.chunkPivotCoordinates.getY(); j < BC_CHUNKS_SETTINGS.height * (chunk.chunkPivotCoordinates.getY() + 1); j++) { + let result = this.terrainGenerator.getValueAt(new Point2D(i, j)); + let resultTile = createTerrainTileFromTileValue(result, new PointInt2D(i * BC_TERRAIN_SETTINGS.totalSize - BC_TERRAIN_SETTINGS.totalSize / 2, j * BC_TERRAIN_SETTINGS.totalSize - BC_TERRAIN_SETTINGS.totalSize / 2)); + resultTile.tileKey = resultTile.worldPosition.getX() + BC_TERRAIN_SETTINGS.totalSize / 2 + "_" + (resultTile.worldPosition.getY() + BC_TERRAIN_SETTINGS.totalSize / 2); + this.addChild(resultTile); + resultTile.drawObject.scale.set(BC_TERRAIN_SETTINGS.scale, BC_TERRAIN_SETTINGS.scale); + resultTile.drawObject.position.set(resultTile.worldPosition.getX(), resultTile.worldPosition.getY()); + resultTile.drawObject.zIndex = resultTile.zOrder; + chunk.addToLayer(CHUNK_LAYER_TERRAIN, resultTile); + chunk.navigationChunk.addToChunk(new NavigationGridTile( + new PointInt2D(i * BC_TERRAIN_SETTINGS.totalSize, j * BC_TERRAIN_SETTINGS.totalSize), + resultTile.navigationCost, + resultTile.isObstacle, + resultTile + ), resultTile.tileKey); + jj++; + } + ii++; + } + chunk.filled = true; + } + + /** + * + * @param {PointInt2D} point in world coordinates + * @returns {Tile | undefined} + */ + getTileAt(point) { + let tileKey = Math.floor(point.getX() / BC_TERRAIN_SETTINGS.totalSize) * BC_TERRAIN_SETTINGS.totalSize + "_" + Math.floor(point.getY() / BC_TERRAIN_SETTINGS.totalSize) * BC_TERRAIN_SETTINGS.totalSize; + let chunkKey = Math.floor(point.getX() / (BC_TERRAIN_SETTINGS.totalSize * BC_CHUNKS_SETTINGS.width)) + "_" + Math.floor(point.getY() / (BC_TERRAIN_SETTINGS.totalSize * BC_CHUNKS_SETTINGS.height)); + let chunk = this.chunkStorage.get(chunkKey); + // console.log(tileKey); + if (chunk) { + return chunk.terrainLayer.get(tileKey); + } + return undefined; + } +} diff --git a/src/Game/WorldGenV2/Terrain/TerrainTilesFactory/TerrainTilesFactory.js b/src/Game/WorldGenV2/Terrain/TerrainTilesFactory/TerrainTilesFactory.js new file mode 100644 index 0000000..52b020e --- /dev/null +++ b/src/Game/WorldGenV2/Terrain/TerrainTilesFactory/TerrainTilesFactory.js @@ -0,0 +1,79 @@ +import { Rectangle } from "../../../../pixi/pixi.mjs"; +import { PRNG } from "../../../GlobalVariables/GlobalVariables"; +import { PointInt2D } from "../../../Utils/Math.utils"; +import { selectRandomValueFromArray } from "../../../Utils/PRNG.utils"; +import { TerrainTile } from "../../Tiles/TerrainTile"; +import { TileValue } from "../Generator/TerrainGenerator"; + +const TERRAIN_TILE_WATER = 0; +const TERRAIN_TILE_SAND = 1; +const TERRAIN_TILE_GRASS = 2; +const TERRAIN_TILE_STONE = 3; +const TERRAIN_TILE_SOIL = 4; + +const TERRAIN_TILE_WATER_Z = 1; +const TERRAIN_TILE_SAND_Z = 0; +const TERRAIN_TILE_GRASS_Z = 4; +const TERRAIN_TILE_STONE_Z = 2; +const TERRAIN_TILE_SOIL_Z = 3; + +const TERRAIN_TILE_WATER_FRAMES = [new Rectangle(1, 1, 32, 32)]; +const TERRAIN_TILE_SAND_FRAMES = [new Rectangle(1, 35, 32, 32), new Rectangle(35, 35, 32, 32), new Rectangle(69, 35, 32, 32), new Rectangle(103, 35, 32, 32)]; +const TERRAIN_TILE_GRASS_FRAMES = [new Rectangle(1, 69, 32, 32), new Rectangle(35, 69, 32, 32), new Rectangle(69, 69, 32, 32)]; +const TERRAIN_TILE_STONE_FRAMES = [new Rectangle(1, 103, 32, 32)]; +const TERRAIN_TILE_SOIL_FRAMES = [new Rectangle(1, 137, 32, 32)]; + +const terrainNavigationCostList = { + 0: 10, //water + 1: 1.7, //sand + 2: 1, //grass + 3: 1.5, //stone + 4: 1.6 //soil +}; + +/** + * + * @param {TileValue} value + * @param {PointInt2D} position + * @returns {TerrainTile | null} + */ +export function createTerrainTileFromTileValue(value, position) { + let t = new TerrainTile(false, position); + t.spriteSheetPath = "assets/images/world/world_terrain_atlas_overlay.png"; + if (value.noiseValue < 0.5) { + t.frame = selectRandomValueFromArray(TERRAIN_TILE_WATER_FRAMES, value.noiseValue); + t.tileId = TERRAIN_TILE_WATER; + t.zOrder = TERRAIN_TILE_WATER_Z; + t.navigationCost = terrainNavigationCostList[TERRAIN_TILE_WATER]; + } else if (value.noiseValue < 0.6) + { + t.frame = selectRandomValueFromArray(TERRAIN_TILE_SAND_FRAMES, value.noiseValue); + t.tileId = TERRAIN_TILE_SAND; + t.zOrder = TERRAIN_TILE_SAND_Z; + t.navigationCost = terrainNavigationCostList[TERRAIN_TILE_SAND]; + } else if (value.noiseValue < 0.8) + { + if(value.temperatureValue >= 0.95 && value.noiseValue >= 0.75) + { + t.frame = selectRandomValueFromArray(TERRAIN_TILE_SOIL_FRAMES, value.noiseValue); + t.tileId = TERRAIN_TILE_SOIL; + t.zOrder = TERRAIN_TILE_SOIL_Z; + t.navigationCost = terrainNavigationCostList[TERRAIN_TILE_SOIL]; + } + else + { + t.frame = selectRandomValueFromArray(TERRAIN_TILE_GRASS_FRAMES, value.noiseValue); + t.tileId = TERRAIN_TILE_GRASS; + t.zOrder = TERRAIN_TILE_GRASS_Z; + t.navigationCost = terrainNavigationCostList[TERRAIN_TILE_GRASS]; + } + } + else + { + t.frame = selectRandomValueFromArray(TERRAIN_TILE_STONE_FRAMES, value.noiseValue); + t.tileId = TERRAIN_TILE_STONE; + t.zOrder = TERRAIN_TILE_STONE_Z; + t.navigationCost = terrainNavigationCostList[TERRAIN_TILE_STONE]; + } + return t; +} diff --git a/src/Game/WorldGenV2/TerrainManager/TerrainManager.js b/src/Game/WorldGenV2/TerrainManager/TerrainManager.js new file mode 100644 index 0000000..083bf5d --- /dev/null +++ b/src/Game/WorldGenV2/TerrainManager/TerrainManager.js @@ -0,0 +1,139 @@ +import { GameObject } from "../../GameObject/GameObject"; +import { addGameObjectToGameState } from "../../GameState/GameState"; +import { BC_CAMERA, BC_CHUNKS_SETTINGS, BC_TERRAIN_SETTINGS } from "../../GlobalVariables/GlobalVariables"; +import { PointInt2D } from "../../Utils/Math.utils"; +import { NavigationGridChunk } from "../../World/NavigationGrid/NavigationGrid"; +import { Chunk } from "../Chunk/Chunk"; +import { Terrain } from "../Terrain/Terrain"; +import { Tile } from "../Tiles/Tile"; + +export class TerrainManger { + /** + * @type {Terrain} + */ + currentTerrain; + + /** + * @type {Array} + */ + #chunkFillingQueue = []; + + /** + * @type {Chunk} + */ + #focusedChunk = null; + #chunkVisibilityPeriod = 0.3; + #currentChunkVisibilityState = 0.0; + + chunkVisibilityOptions = { + min: -2, + max: 3, + }; + + /** + * + * @returns {Terrain} + */ + createNewTerrain() { + let t = new Terrain(false); + addGameObjectToGameState(t); + return t; + } + + /** + * + * @param {PointInt2D} pivot + * @returns {Chunk} + */ + createNewChunk(pivot) { + let t = new Chunk(false, pivot); + addGameObjectToGameState(t); + t.navigationChunk = new NavigationGridChunk(); + return t; + } + + tickHandler(ticker) { + // console.log(this.currentTerrain); + if (this.#chunkFillingQueue.length > 0) { + this.currentTerrain.fillChunk(this.#chunkFillingQueue.pop()); + } + this.#currentChunkVisibilityState += ticker.deltaMS / 1000; + if (this.#currentChunkVisibilityState >= this.#chunkVisibilityPeriod) { + this.handleChunkVisibility(); + this.#currentChunkVisibilityState = 0.0; + } + } + + /** + * adds chunk to terrain. Chunk object must contain pivot coordinates. This function is a part of terrain manager interface. + * @param {Chunk} chunk + */ + addChunk(chunk) { + this.currentTerrain.addChunk(chunk); + if (!chunk.filled) this.#chunkFillingQueue.push(chunk); + } + + /** + * + * @param {PointInt2D} point + */ + getChunkAt(point) + { + let w = BC_CHUNKS_SETTINGS.width * BC_TERRAIN_SETTINGS.totalSize; + let h = BC_CHUNKS_SETTINGS.height * BC_TERRAIN_SETTINGS.totalSize; + let chunkId = Math.floor(point.getX() / w) + "_" + Math.floor(point.getY() / h); + return this.currentTerrain.chunkStorage.get(chunkId); + } + + /** + * update tile in terrain + * @param {Tile} tile new tile + * @param {Number} layerId chunk layer id + * @param {PointInt2D} coordinates world coordinates + */ + updateTile(tile, layer, coordinates) {} + + addEntity() {} + + /** + * + * @param {PointInt2D} point in world coordinates + * @returns {Tile | undefined} + */ + getTileAt(point) { + return this.currentTerrain.getTileAt(point); + } + + handleChunkVisibility() { + 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 cx = Math.floor(BC_CAMERA.position.x / w); + let cy = Math.floor(BC_CAMERA.position.y / h); + let chunkId = cx + "_" + cy; + if (!this.#focusedChunk || !GameObject.isEqual(this.#focusedChunk, this.currentTerrain.chunkStorage.get(chunkId))) { + for (const i of this.currentTerrain.visibleChunks) { + i[1].changeVisibility(false); + } + this.currentTerrain.visibleChunks.clear(); + let t_chunkId; + let t_chunk; + for (let i = this.chunkVisibilityOptions.min; i < this.chunkVisibilityOptions.max; i++) { + for (let j = this.chunkVisibilityOptions.min; j < this.chunkVisibilityOptions.max; j++) { + t_chunkId = cx + i + "_" + (cy + j); + if (this.currentTerrain.chunkStorage.has(t_chunkId)) { + t_chunk = this.currentTerrain.chunkStorage.get(t_chunkId); + t_chunk.changeVisibility(true); + if (i === 0 && j === 0) this.#focusedChunk = t_chunk; + this.currentTerrain.visibleChunks.set(t_chunkId, t_chunk); + } else { + t_chunk = this.createNewChunk(new PointInt2D(cx + i, cy + j)); + this.#chunkFillingQueue.push(t_chunk); + if (i === 0 && j === 0) this.#focusedChunk = t_chunk; + this.currentTerrain.addChunk(t_chunk); + this.currentTerrain.visibleChunks.set(t_chunkId, t_chunk); + } + } + } + } + } +} diff --git a/src/Game/WorldGenV2/Tiles/TerrainTile.js b/src/Game/WorldGenV2/Tiles/TerrainTile.js new file mode 100644 index 0000000..83fbbc6 --- /dev/null +++ b/src/Game/WorldGenV2/Tiles/TerrainTile.js @@ -0,0 +1,10 @@ +import { SceneObject } from "../../SceneObjects/SceneObject"; +import { Tile } from "./Tile"; + +export class TerrainTile extends Tile +{ + constructor(tickable, position) + { + super(tickable, position); + } +} \ No newline at end of file diff --git a/src/Game/WorldGenV2/Tiles/Tile.js b/src/Game/WorldGenV2/Tiles/Tile.js new file mode 100644 index 0000000..6fc08fb --- /dev/null +++ b/src/Game/WorldGenV2/Tiles/Tile.js @@ -0,0 +1,32 @@ +import { Rectangle } from "../../../pixi/pixi.mjs"; +import { SceneObject } from "../../SceneObjects/SceneObject"; +import { PointInt2D } from "../../Utils/Math.utils"; +import { getSpriteFromAtlas } from "../../Utils/Sprites.utils"; + +export class Tile extends SceneObject +{ + tileId = 0; + spriteSheetPath = ""; + frame = new Rectangle(); + tileKey = ""; + zOrder = -1; + navigationCost = -1; + isObstacle = false; + + /** + * + * @param {Boolean} tickable + * @param {PointInt2D} position + */ + constructor(tickable, position) + { + super(tickable); + this.worldPosition = position; + } + + onInit() + { + super.onInit(); + this.drawObject = getSpriteFromAtlas(this.spriteSheetPath, this.frame); + }; +} \ No newline at end of file diff --git a/src/Game/WorldGenV2/WorldGenV2.js b/src/Game/WorldGenV2/WorldGenV2.js new file mode 100644 index 0000000..14ce975 --- /dev/null +++ b/src/Game/WorldGenV2/WorldGenV2.js @@ -0,0 +1,19 @@ + +// const FIRST_CHUNKS_SIZE = 3; + +import { addGameObjectToGameState } from "../GameState/GameState"; +import { BC_CAMERA, BC_CHUNKS_SETTINGS, BC_TERRAIN_MANAGER, BC_TERRAIN_SETTINGS } from "../GlobalVariables/GlobalVariables"; +import { PointInt2D } from "../Utils/Math.utils"; +import { Chunk } from "./Chunk/Chunk"; + +export function generateFirstChunks() { + let w = BC_CHUNKS_SETTINGS.width * BC_TERRAIN_SETTINGS.totalSize; + let h = BC_CHUNKS_SETTINGS.height * BC_TERRAIN_SETTINGS.totalSize; + for (let i = -1; i < 2; i++) { + for (let j = -1; j < 2; j++) { + let chunkPivot = new PointInt2D(Math.floor((BC_CAMERA.position.x + w * i) / w), Math.floor((BC_CAMERA.position.y + h * j) / h)); + let chunk = BC_TERRAIN_MANAGER.createNewChunk(chunkPivot); + BC_TERRAIN_MANAGER.addChunk(chunk); + } + } +} \ No newline at end of file diff --git a/src/Game/WorldGeneration/TerrainGenerator/TerrainGenerator.js b/src/Game/WorldGeneration/TerrainGenerator/TerrainGenerator.js deleted file mode 100644 index f791139..0000000 --- a/src/Game/WorldGeneration/TerrainGenerator/TerrainGenerator.js +++ /dev/null @@ -1,57 +0,0 @@ -import {Noise} from "noisejs"; -import { BC_CHUNKS_SETTINGS, PRNG } from "../../GlobalVariables/GlobalVariables"; -import { clampNumber } from "../../Utils/Math.utils"; -import { DWFBMSimplex2, FBMSimplex2 } from "../../Utils/Noise.utils"; - -/** - * Terrain generator - * - * cNoise 1:100 - continent type - * mNoise 1:20 - mountains - */ - -let cNoise = new Noise(Math.floor(PRNG() * 999999999999)); -let tNoise = new Noise(Math.floor(PRNG() * 999999999999)); - -export function genTerrain(xMin, xMax, yMin, yMax) -{ - /** - * @type {Array} - */ - let terrainResult = new Array(BC_CHUNKS_SETTINGS.width * BC_CHUNKS_SETTINGS.height); - let mainValue = 0; - let mountainsValue = 0; - let temperatureValue = 0; - - let ii = 0; - let jj = 0; - for (let i = xMin; i < xMax; i++) { - jj = 0; - for (let j = yMin; j < yMax; j++) { - mainValue = DWFBMSimplex2(cNoise, i / 1000.0, j / 1000.0, 3.0); - mainValue *= mainValue; - temperatureValue = DWFBMSimplex2(tNoise, i / 1000.0, j / 1000.0, 3.0); - // mainValue = Math.abs(temperatureValue - mainValue); - // if(temperatureValue > 0.5) - // { - mainValue *= DWFBMSimplex2(cNoise, i / 100, j / 100, 3.0); - // } - // mountainsValue = _normalizeNoiseValue(mNoise.simplex2(i / 200, j / 200)); - // mainValue += clampNumber(Math.pow(mountainsValue * 2, 5), 0.0, 1.0); - // mainValue = clampNumber(mainValue, 0.0, 0.99); - terrainResult[ii * BC_CHUNKS_SETTINGS.width + jj] = mainValue; - // //soil - // if(continentValue > 0.5) - // { - // terrainResult[ii * BC_CHUNKS_SETTINGS.width + jj] = continentValue; - // } - // else //water - // { - // terrainResult[ii * BC_CHUNKS_SETTINGS.width + jj] = continentValue * 0.3; - // } - jj++; - } - ii++; - } - return terrainResult; -} \ No newline at end of file diff --git a/src/Game/WorldGeneration/TerrainPredefines/TerrainPredefines.js b/src/Game/WorldGeneration/TerrainPredefines/TerrainPredefines.js deleted file mode 100644 index 75e7731..0000000 --- a/src/Game/WorldGeneration/TerrainPredefines/TerrainPredefines.js +++ /dev/null @@ -1,47 +0,0 @@ -import { Rectangle } from "../../../pixi/pixi.mjs"; - -class _type_TerrainTilesMapPreDefinition -{ - /** - * @type {Array} - */ - textureVariations; - /** - * @type {Number} - */ - textureVariationsNumber; - /** - * @type {Number} - */ - zIndex; -} - -/** - * @type {Array<_type_TerrainTilesMapPreDefinition>} - */ -export const TerrainTilesMapPreDefinition = { - //water - 0: { - textureVariations: [new Rectangle(1, 1, 32, 32)], - textureVariationsNumber: 1, - zIndex: 4, - }, - //sand - 1: { - textureVariations: [new Rectangle(1, 35, 32, 32), new Rectangle(35, 35, 32, 32), new Rectangle(69, 35, 32, 32), new Rectangle(103, 35, 32, 32)], - textureVariationsNumber: 4, - zIndex: 2, - }, - //grass - 2: { - textureVariations: [new Rectangle(1, 69, 32, 32), new Rectangle(35, 69, 32, 32), new Rectangle(69, 69, 32, 32)], - textureVariationsNumber: 3, - zIndex: 3, - }, - //stone - 3: { - textureVariations: [new Rectangle(1, 103, 32, 32)], - textureVariationsNumber: 1, - zIndex: 1, - }, -}; diff --git a/src/Game/WorldGeneration/WorldChunk/WorldGenChunk.js b/src/Game/WorldGeneration/WorldChunk/WorldGenChunk.js deleted file mode 100644 index 3119205..0000000 --- a/src/Game/WorldGeneration/WorldChunk/WorldGenChunk.js +++ /dev/null @@ -1,116 +0,0 @@ -import { Container } from "../../../pixi/pixi.mjs"; -import { SceneObject } from "../../SceneObjects/SceneObject"; -import { worldCoordinatesToChunkIndexesCoordinates, worldCoordinatesToChunkLocalCoordinates } from "../WorldGen"; -import { TerrainTile } from "../WorldObjects/TerrainTile/TerrainTile"; -import { VegetationTile } from "../WorldObjects/VegetationTile/VegetationTile"; -import { NavigationGridChunk } from "../../World/NavigationGrid/NavigationGrid"; - -export class ChunkStorageTypes -{ - static TYPE_TERRAIN = 0; - static TYPE_VEGETATION = 1; - static TYPE_BUILDINGS = 2; - static TYPE_NPC = 3; -}; - -export class WorldChunk extends SceneObject -{ - /** - * @type Map - */ - terrainStorage = new Map(); - /** - * @type Map - */ - vegetationStorage = new Map(); - /** - * @type Map - */ - buildingsStorage = new Map(); - /** - * @type Map - */ - npcStorage = new Map(); - - /** - * @type NavigationGridChunk - */ - navigationGridChunk = new NavigationGridChunk(); - - /** - * property to handle chunk visibility - */ - centralChunk = false; - - /** - * - * @param {SceneObject} object - * @param {ChunkStorageTypes} storageType - * @param {String} objectId - */ - addToChunk(object, storageType, objectId) - { - switch (storageType) { - case ChunkStorageTypes.TYPE_TERRAIN: - this.terrainStorage.set(objectId, object); - break; - case ChunkStorageTypes.TYPE_VEGETATION: - this.vegetationStorage.set(objectId, object); - break; - case ChunkStorageTypes.TYPE_BUILDINGS: - this.buildingsStorage.set(objectId, object); - break; - default: - return false; - } - this.drawObject.addChild(object.drawObject); - return true; - } - - /** - * - * @param {SceneObject} object - * @param {ChunkStorageTypes} storageType - * @param {String} objectId - */ - removeFromChunk(object, storageType, objectId) - { - switch (storageType) { - case ChunkStorageTypes.TYPE_TERRAIN: - this.terrainStorage.delete(objectId); - break; - case ChunkStorageTypes.TYPE_VEGETATION: - this.vegetationStorage.delete(objectId); - break; - case ChunkStorageTypes.TYPE_BUILDINGS: - this.buildingsStorage.delete(objectId); - break; - default: - return false; - } - this.drawObject.removeChild(object.drawObject); - return true; - }; - - /** - * - * @param {Number} xWorld - * @param {Number} yWorld - * @param {ChunkStorageTypes} storageType - * @returns SceneObject or undefined - */ - getFromChunk(xWorld, yWorld, storageType) - { - let coords = worldCoordinatesToChunkLocalCoordinates(xWorld, yWorld); - switch (storageType) { - case ChunkStorageTypes.TYPE_TERRAIN: - return this.terrainStorage.get(coords.x + "_" + coords.y); - case ChunkStorageTypes.TYPE_VEGETATION: - return this.vegetationStorage.get(coords.x + "_" + coords.y); - case ChunkStorageTypes.TYPE_BUILDINGS: - return this.buildingsStorage.get(coords.x + "_" + coords.y); - default: - return undefined; - } - } -}; \ No newline at end of file diff --git a/src/Game/WorldGeneration/WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater.js b/src/Game/WorldGeneration/WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater.js deleted file mode 100644 index c0bbc59..0000000 --- a/src/Game/WorldGeneration/WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater.js +++ /dev/null @@ -1,79 +0,0 @@ -import { BC_CAMERA, BC_CHUNKS_SETTINGS, BC_CURRENT_SCENE, BC_TERRAIN_SETTINGS } from "../../GlobalVariables/GlobalVariables"; -import { fillWorldGenChunk, getWorldChunkById, setWorldChunkById, worldChunkExists } from "../WorldGen"; -import { WorldChunk } from "../WorldChunk/WorldGenChunk"; - -export class WorldChunksVisibilityUpdater { - static _chunksFillingQueue = []; - static _currentIndex = -1; - /** - * @type Map - */ - static _visibleChunks = new Map(); - static enableAutoWorldChunksGeneration = false; - - static _chunksVisibilityRange = { - min: -2, - max: 3 - }; - - // static { - // this.visibleChunks = new Map(); - // }; - - static addChunkToFillingQueue(chunk, x, y) { - this._chunksFillingQueue.push({ chunk, x, y }); - this._currentIndex++; - } - - /** - * Ticker function - */ - static handleWorldChunkFilling() { - if (this._currentIndex < 0) return; - fillWorldGenChunk( - this._chunksFillingQueue[this._currentIndex].chunk, - this._chunksFillingQueue[this._currentIndex].x, - this._chunksFillingQueue[this._currentIndex].y - ); - this._chunksFillingQueue.pop(); - this._currentIndex--; - } - - - /** - * Ticker function - */ - static handleWorldChunksVisibility() { - 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 cx = Math.floor(BC_CAMERA.position.x / w); - let cy = Math.floor(BC_CAMERA.position.y / h); - let chunkId = cx + "_" + cy; - if ((this._visibleChunks.has(chunkId) && !this._visibleChunks.get(chunkId).centralChunk) || !this._visibleChunks.has(chunkId)) { - for (const visChunk of this._visibleChunks) { - visChunk[1].drawObject.visible = false; - } - this._visibleChunks.clear(); - for (let i = this._chunksVisibilityRange.min; i < this._chunksVisibilityRange.max; i++) { - for (let j = this._chunksVisibilityRange.min; j < this._chunksVisibilityRange.max; j++) { - let t_chunkId = (cx + i) + "_" + (cy + j); - if (worldChunkExists(t_chunkId)) { - let wChunk = getWorldChunkById(t_chunkId); - wChunk.centralChunk = (i === 0 && j === 0); - this._visibleChunks.set(t_chunkId, wChunk); - wChunk.drawObject.visible = true; - } else if (this.enableAutoWorldChunksGeneration) { - let newChunk = new WorldChunk(false); - BC_CURRENT_SCENE.addObjectToSceneWithInitialization(newChunk); - newChunk.drawObject.position.set(w * (cx + i), h * (cy + j)); - this.addChunkToFillingQueue(newChunk, cx + i, cy + j); - this._visibleChunks.set(t_chunkId, newChunk); - newChunk.drawObject.visible = true; - newChunk.centralChunk = (i === 0 && j === 0); - setWorldChunkById(newChunk, t_chunkId); - } - } - } - } - } -} diff --git a/src/Game/WorldGeneration/WorldGen.js b/src/Game/WorldGeneration/WorldGen.js deleted file mode 100644 index 002e01d..0000000 --- a/src/Game/WorldGeneration/WorldGen.js +++ /dev/null @@ -1,269 +0,0 @@ -import { Noise } from "noisejs"; -import { Rectangle } from "../../pixi/pixi.mjs"; -import { BC_CAMERA, BC_CHUNKS_SETTINGS, BC_CURRENT_SCENE, BC_SPRITES_SETTINGS, BC_TERRAIN_SETTINGS, PRNG } from "../GlobalVariables/GlobalVariables"; -import { NumberCue, RGBColor } from "../Utils/DataTypes.utils"; -import { ChunkStorageTypes, WorldChunk } from "./WorldChunk/WorldGenChunk"; -import { TerrainTile, TerrainTileProps } from "./WorldObjects/TerrainTile/TerrainTile"; -import { Point2D, PointInt2D, clampNumber } from "../Utils/Math.utils"; -import { addGameObjectToGameState } from "../GameState/GameState"; -import { VegetationTile, VegetationTileProps } from "./WorldObjects/VegetationTile/VegetationTile"; -import { WorldChunksVisibilityUpdater } from "./WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater"; -import { NavigationGridChunk, NavigationGridTile } from "../World/NavigationGrid/NavigationGrid"; -import { genTerrain } from "./TerrainGenerator/TerrainGenerator"; -import { TerrainTilesMapPreDefinition } from "./TerrainPredefines/TerrainPredefines"; - -/** - * @type Map - */ -const WorldChunksStorage = new Map(); - -/* #### REWRITE PART START ####*/ -const terrainSpriteList = { - 0: { x: 20, y: 20 }, //water - 1: { x: 0, y: 20 }, //sand - 2: { x: 0, y: 0 }, //grass - 3: { x: 20, y: 0 }, //stone -}; -const terrainTypeList = { - 0: "ter_water", //water - 1: "ter_sand", //sand - 2: "ter_grass", //grass - 3: "ter_stone", //stone -}; -const terrainNavigationCostList = { - 0: 10, //water - 1: 1.7, //sand - 2: 1, //grass - 3: 1.5, //stone -}; -const grassVegetationSpriteList = { - 0: { x: 10, y: 11 }, - 1: { x: 11, y: 11 }, - 2: { x: 12, y: 11 }, - 3: { x: 13, y: 11 }, - 4: { x: 14, y: 11 }, - 5: { x: 15, y: 11 }, - 6: { x: 16, y: 11 }, - 7: { x: 17, y: 11 }, - 8: { x: 18, y: 11 }, - 9: { x: 19, y: 11 }, - 10: { x: 0, y: 12 }, - 11: { x: 1, y: 12 }, - 12: { x: 2, y: 12 }, - 13: { x: 3, y: 12 }, - 14: { x: 7, y: 13 }, - 15: { x: 7, y: 12 }, - 16: { x: 8, y: 12 }, - 17: { x: 9, y: 12 }, -}; -const grassVegResourcesList = { - 0: { type: "grass", num: 10 / 5 }, - 1: { type: "grass", num: 9 / 5 }, - 2: { type: "grass", num: 8 / 5 }, - 3: { type: "grass", num: 7 / 5 }, - 4: { type: "grass", num: 4 / 5 }, - 5: { type: "grass", num: 4 / 5 }, - 6: { type: "grass", num: 5 / 5 }, - 7: { type: "grass", num: 3 / 5 }, - 8: { type: "grass", num: 2 / 5 }, - 9: { type: "grass", num: 1 / 5 }, - 10: { type: "grass", num: 2 / 5 }, - 11: { type: "grass", num: 2 / 5 }, - 12: { type: "grass", num: 2 / 5 }, - 13: { type: "grass", num: 2 / 5 }, - 14: { type: "stone", num: 1 / 5 }, - 15: { type: "wood", num: 2 / 5 }, - 16: { type: "wood", num: 2 / 5 }, - 17: { type: "wood", num: 2 / 5 }, -}; - -export function worldCoordinatesToChunkIndex(x, y) { - 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; - // console.log(w, h); - return { x: Math.floor(x / w), y: Math.floor(y / h) }; -} -export function worldCoordinatesToChunkIndexesCoordinates(x, y) { - let ws = BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale; - let hs = BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale; - return { x: Math.floor(x / ws), y: Math.floor(y / hs) }; -} - -export function worldCoordinatesToChunkLocalCoordinates(x, y) { - let ws = BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale; - let hs = BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale; - if (x < 0 && y >= 0) { - return { - x: (BC_CHUNKS_SETTINGS.width - (Math.ceil(Math.abs(x) / ws) % BC_CHUNKS_SETTINGS.width)) % BC_CHUNKS_SETTINGS.width, - y: Math.floor(Math.abs(y) / hs) % BC_CHUNKS_SETTINGS.height, - }; - } else if (x < 0 && y < 0) - return { - x: (BC_CHUNKS_SETTINGS.width - (Math.ceil(Math.abs(x) / ws) % BC_CHUNKS_SETTINGS.width)) % BC_CHUNKS_SETTINGS.width, - y: (BC_CHUNKS_SETTINGS.height - (Math.ceil(Math.abs(y) / hs) % BC_CHUNKS_SETTINGS.height)) % BC_CHUNKS_SETTINGS.height, - }; - else if (x >= 0 && y < 0) - return { - x: Math.floor(Math.abs(x) / ws) % BC_CHUNKS_SETTINGS.width, - y: (BC_CHUNKS_SETTINGS.height - (Math.ceil(Math.abs(y) / hs) % BC_CHUNKS_SETTINGS.height)) % BC_CHUNKS_SETTINGS.height, - }; - else { - return { - x: Math.floor(Math.abs(x) / ws) % BC_CHUNKS_SETTINGS.width, - y: Math.floor(Math.abs(y) / hs) % BC_CHUNKS_SETTINGS.height, - }; - } -} - -export function getWorldChunkAt(xWorld, yWorld) { - let t = worldCoordinatesToChunkIndex(xWorld, yWorld); - return WorldChunksStorage.get(t.x + "_" + t.y); -} - -export function getWorldChunkById(id) { - return WorldChunksStorage.get(id); -} - -/** - * - * @param {Number} xWorld - * @param {Number} yWorld - * @param {ChunkStorageTypes} storageType - * @returns {} - */ -export function getTileAt(xWorld, yWorld, storageType) { - let c = getWorldChunkAt(xWorld, yWorld); - if (!c) return undefined; - return c.getFromChunk(xWorld, yWorld, storageType); -} - -export function worldChunkExists(id) { - return WorldChunksStorage.has(id); -} - -export function setWorldChunkById(chunk, id) { - WorldChunksStorage.set(id, chunk); -} - -let noise = new Noise(Math.floor(PRNG() * 188822321)); -let noiseErosion = new Noise(Math.floor(PRNG() * 327749029)); -let noiseBiomes = new Noise(Math.floor(PRNG() * 927472011)); - -let terrainCue = new NumberCue([0, 1, 2, 3, 3], [0.0, 0.25, 0.5, 0.75, 1.1]); -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.1]); - -/** - * - * @param {WorldChunk} chunk chunk to fill - * @param {Number} x ceiled coordinates of left-upper corner - * @param {Number} y ceiled coordinates of left-upper corner - */ -export function fillWorldGenChunk(chunk, x, y) { - let ii = 0; - let jj = 0; - let terrainData = genTerrain(BC_CHUNKS_SETTINGS.width * x, BC_CHUNKS_SETTINGS.width * (x + 1), BC_CHUNKS_SETTINGS.height * y, BC_CHUNKS_SETTINGS.height * (y + 1)); - // console.log(terrainData); - 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.025, j * 0.025) + 1) / 2; - let res; - res = terrainData[ii * BC_CHUNKS_SETTINGS.width + jj]; - // 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); - // } - - let sTint = new RGBColor(255, 255, 255).multiplyByNumber(terrainTintCue.getValueAt(res)).toNumber(); - res = Math.floor(terrainCue.getValueAt(res)); - - let terrainTile = new TerrainTile(false); - let tilePreDefines = TerrainTilesMapPreDefinition[res]; - terrainTile.spriteSheetPath = "assets/images/world/world_terrain_atlas_overlay.png"; - terrainTile.frame = tilePreDefines.textureVariations[Math.floor(PRNG() * (tilePreDefines.textureVariationsNumber - 1))]; - terrainTile.props = new TerrainTileProps(terrainTypeList[res], res * 5, terrainNavigationCostList[res]); - terrainTile.worldPosition = new Point2D( - i * BC_TERRAIN_SETTINGS.scale * BC_TERRAIN_SETTINGS.tileSize, - j * BC_TERRAIN_SETTINGS.scale * BC_TERRAIN_SETTINGS.tileSize - ); - - addGameObjectToGameState(terrainTile); - - terrainTile.drawObject.tint = sTint; - terrainTile.drawObject.zIndex = 1 + tilePreDefines.zIndex; - // terrainTile.drawObject.pivot.set(BC_SPRITES_SETTINGS.defaultSize * 0.5, BC_SPRITES_SETTINGS.defaultSize * 0.5); - terrainTile.drawObject.position.set(16 * BC_SPRITES_SETTINGS.scale * (ii) - 8 * BC_SPRITES_SETTINGS.scale, 16 * BC_SPRITES_SETTINGS.scale * (jj) - 8 * BC_SPRITES_SETTINGS.scale); - terrainTile.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale); - - chunk.addToChunk(terrainTile, ChunkStorageTypes.TYPE_TERRAIN, ii + "_" + jj); - chunk.navigationGridChunk.addToChunk( - new NavigationGridTile( - new PointInt2D(i * BC_TERRAIN_SETTINGS.scale * BC_TERRAIN_SETTINGS.tileSize, j * BC_TERRAIN_SETTINGS.scale * BC_TERRAIN_SETTINGS.tileSize), - terrainNavigationCostList[res], - terrainNavigationCostList[res] > 100, - terrainTile - ), - ii + "_" + jj - ); - // NavigationGrid.addToNavigationGrid(new PointInt2D(ii, jj), terrainNavigationCostList[res], terrainNavigationCostList[res] > 100); - - if (res === 2 && PRNG() > 0.9) { - let rv = Math.floor(PRNG() * 18); - - let vegetationTile = new VegetationTile(false); - vegetationTile.spriteSheetPath = "assets/images/world/vegetation_ts.png"; - vegetationTile.frame = new Rectangle(16 * grassVegetationSpriteList[rv].x, 16 * grassVegetationSpriteList[rv].y, 16, 16); - vegetationTile.props = new VegetationTileProps("vegetation", grassVegResourcesList[rv]); - vegetationTile.worldPosition = new Point2D( - i * BC_TERRAIN_SETTINGS.scale * BC_TERRAIN_SETTINGS.tileSize, - j * BC_TERRAIN_SETTINGS.scale * BC_TERRAIN_SETTINGS.tileSize - ); - - addGameObjectToGameState(vegetationTile); - - vegetationTile.drawObject.tint = sTint; - vegetationTile.drawObject.zIndex = 10; - vegetationTile.drawObject.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj); - vegetationTile.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale); - - chunk.addToChunk(vegetationTile, ChunkStorageTypes.TYPE_VEGETATION, ii + "_" + jj); - chunk.navigationGridChunk.changeNavigationGridTileSettings(ii + "_" + jj, (tile)=>{ - tile.movementCost *= 1.5; - }); - - jj++; - continue; - } - jj++; - } - ii++; - } -} - -export function createFirstWorldChunks() { - 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; - for (let i = -2; i < 3; i++) { - for (let j = -2; j < 3; j++) { - let chunkXCeiled = Math.floor((BC_CAMERA.position.x + w * i) / w); - let chunkYCeiled = Math.floor((BC_CAMERA.position.y + h * j) / h); - let chunkId = chunkXCeiled + "_" + chunkYCeiled; - - let chunk = new WorldChunk(false); - // chunk.navigationGridChunk = new NavigationGridChunk(); - chunk.drawObject.position.set(w * chunkXCeiled, h * chunkYCeiled); - chunk.props = { id: chunkId }; - BC_CURRENT_SCENE.addObjectToSceneWithInitialization(chunk); - - fillWorldGenChunk(chunk, chunkXCeiled, chunkYCeiled); - WorldChunksStorage.set(chunkId, chunk); - } - } - WorldChunksVisibilityUpdater.enableAutoWorldChunksGeneration = true; -} - -/* #### REWRITE PART END ####*/ diff --git a/src/Game/WorldGeneration/WorldObjects/BuildingTile/BuildingTile.js b/src/Game/WorldGeneration/WorldObjects/BuildingTile/BuildingTile.js deleted file mode 100644 index 0a931ef..0000000 --- a/src/Game/WorldGeneration/WorldObjects/BuildingTile/BuildingTile.js +++ /dev/null @@ -1,41 +0,0 @@ -import { Rectangle } from "../../../../pixi/pixi.mjs"; -import { SceneObject } from "../../../SceneObjects/SceneObject"; -import { getSpriteFromAtlas } from "../../../Utils/Sprites.utils"; - -export class BuildingTileProps -{ - /** - * @type String - */ - type; - /** - * @type Number - */ - price; - - /** - * - * @param {String} type - * @param {Number} price - */ - constructor(type = "", price = 0) - { - this.type = type; - this.price = price; - }; - - -} - -export class BuildingTile extends SceneObject -{ - props = new BuildingTileProps(); - spriteSheetPath = ""; - frame = new Rectangle(); - - onInit() - { - super.onInit(); - this.drawObject = getSpriteFromAtlas(this.spriteSheetPath, this.frame); - }; -}; \ No newline at end of file diff --git a/src/Game/WorldGeneration/WorldObjects/TerrainTile/TerrainTile.js b/src/Game/WorldGeneration/WorldObjects/TerrainTile/TerrainTile.js deleted file mode 100644 index 9cf157d..0000000 --- a/src/Game/WorldGeneration/WorldObjects/TerrainTile/TerrainTile.js +++ /dev/null @@ -1,49 +0,0 @@ -import { Rectangle } from "../../../../pixi/pixi.mjs"; -import { SceneObject } from "../../../SceneObjects/SceneObject"; -import { getSpriteFromAtlas } from "../../../Utils/Sprites.utils"; - -export class TerrainTileProps -{ - /** - * @type String - */ - type; - - /** - * @type Number - */ - temperature; - - /** - * @type Number - */ - navigationCost = 1000; - - /** - * - * @param {String} type - * @param {Number} temperature - * @param {Number} navigationCost - */ - constructor(type = "", temperature = 0, navigationCost = 0) - { - this.type = type; - this.temperature = temperature; - this.navigationCost = navigationCost; - }; - - -} - -export class TerrainTile extends SceneObject -{ - props = new TerrainTileProps(); - spriteSheetPath = ""; - frame = new Rectangle(); - - onInit() - { - super.onInit(); - this.drawObject = getSpriteFromAtlas(this.spriteSheetPath, this.frame); - }; -}; \ No newline at end of file diff --git a/src/Game/WorldGeneration/WorldObjects/VegetationTile/VegetationTile.js b/src/Game/WorldGeneration/WorldObjects/VegetationTile/VegetationTile.js deleted file mode 100644 index 16070cc..0000000 --- a/src/Game/WorldGeneration/WorldObjects/VegetationTile/VegetationTile.js +++ /dev/null @@ -1,53 +0,0 @@ -import { Rectangle } from "../../../../pixi/pixi.mjs"; -import { GameObject } from "../../../GameObject/GameObject"; -import { PRNG } from "../../../GlobalVariables/GlobalVariables"; -import { SceneObject } from "../../../SceneObjects/SceneObject"; -import { getSpriteFromAtlas } from "../../../Utils/Sprites.utils"; -import { ChunkStorageTypes } from "../../WorldChunk/WorldGenChunk"; - -export class VegetationTileProps -{ - /** - * @type String - */ - type; - /** - * @type any - */ - resourcesList; - - /** - * - * @param {String} type - * @param {any} resourcesList - */ - constructor(type = "", resourcesList = {}) - { - this.type = type; - this.resourcesList = resourcesList; - }; - - -} - -export class VegetationTile extends SceneObject -{ - props = new VegetationTileProps(); - spriteSheetPath = ""; - frame = new Rectangle(); - - /** - * - * @param {Boolean} tickAble - */ - constructor(tickAble = false) - { - super(tickAble); - } - - onInit() - { - super.onInit(); - this.drawObject = getSpriteFromAtlas(this.spriteSheetPath, this.frame); - }; -}; \ No newline at end of file