terrain generation improvement
This commit is contained in:
parent
d1c3766c98
commit
0fe482a152
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -2,6 +2,8 @@
|
|||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"Alea",
|
"Alea",
|
||||||
"amogus",
|
"amogus",
|
||||||
|
"DDFBM",
|
||||||
|
"DWFBM",
|
||||||
"PIXI",
|
"PIXI",
|
||||||
"spritesheet"
|
"spritesheet"
|
||||||
]
|
]
|
||||||
|
BIN
public/assets/images/world/world_terrain_atlas_overlay.ase
Normal file
BIN
public/assets/images/world/world_terrain_atlas_overlay.ase
Normal file
Binary file not shown.
BIN
public/assets/images/world/world_terrain_atlas_overlay.png
Normal file
BIN
public/assets/images/world/world_terrain_atlas_overlay.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
@ -4,7 +4,7 @@ import { loadPixelAsset } from "../Utils/Assets.utils";
|
|||||||
export async function loadGameAssets()
|
export async function loadGameAssets()
|
||||||
{
|
{
|
||||||
UIAssetsLoaderInfoPipe.update((s)=>{
|
UIAssetsLoaderInfoPipe.update((s)=>{
|
||||||
s.totalToDownload = 5;
|
s.totalToDownload = 6;
|
||||||
s.downloaded = 0;
|
s.downloaded = 0;
|
||||||
});
|
});
|
||||||
// await loadPixelAsset("assets/images/amogus.png");
|
// await loadPixelAsset("assets/images/amogus.png");
|
||||||
@ -43,6 +43,10 @@ export async function loadGameAssets()
|
|||||||
UIAssetsLoaderInfoPipe.update((s)=>{
|
UIAssetsLoaderInfoPipe.update((s)=>{
|
||||||
s.downloaded += 1;
|
s.downloaded += 1;
|
||||||
});
|
});
|
||||||
|
await loadPixelAsset("assets/images/world/world_terrain_atlas_overlay.png");
|
||||||
|
UIAssetsLoaderInfoPipe.update((s)=>{
|
||||||
|
s.downloaded += 1;
|
||||||
|
});
|
||||||
await loadPixelAsset("assets/images/selection.png");
|
await loadPixelAsset("assets/images/selection.png");
|
||||||
UIAssetsLoaderInfoPipe.update((s)=>{
|
UIAssetsLoaderInfoPipe.update((s)=>{
|
||||||
s.downloaded += 1;
|
s.downloaded += 1;
|
||||||
|
@ -55,13 +55,18 @@ function setupInGameSelector() {
|
|||||||
let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y);
|
let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y);
|
||||||
// let tChunk = getWorldChunkAt(t.x, t.y);
|
// let tChunk = getWorldChunkAt(t.x, t.y);
|
||||||
// let tTerrainTile = tChunk.getFromChunk(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN);
|
// let tTerrainTile = tChunk.getFromChunk(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];
|
||||||
|
});
|
||||||
|
|
||||||
t.x = BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale * Math.floor(t.x / (BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale));
|
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));
|
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);
|
sprite0.position.set(t.x, t.y);
|
||||||
};
|
};
|
||||||
|
|
||||||
BC_VIEWPORT.onpointerdown = (e) =>
|
BC_VIEWPORT.onclick = (e) =>
|
||||||
{
|
{
|
||||||
let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y);
|
let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y);
|
||||||
// console.log(getNavigationGridTile(t.x, t.y));
|
// console.log(getNavigationGridTile(t.x, t.y));
|
||||||
|
41
src/Game/Utils/Noise.utils.js
Normal file
41
src/Game/Utils/Noise.utils.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { Noise } from "noisejs";
|
||||||
|
import { clampNumber } from "./Math.utils";
|
||||||
|
|
||||||
|
function _normalizeNoiseValue(value)
|
||||||
|
{
|
||||||
|
return (value+1)*0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fractal Brownian Motion
|
||||||
|
* @param {Noise} noiseRef
|
||||||
|
* @param {Number} octaves
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
*/
|
||||||
|
export function FBMSimplex2(noiseRef, octaves = 8, x, y)
|
||||||
|
{
|
||||||
|
let value = 0;
|
||||||
|
let freq = 1.0;
|
||||||
|
let amplitude = 1.0;
|
||||||
|
for (let i = 0; i < octaves; i++) {
|
||||||
|
value += _normalizeNoiseValue(noiseRef.simplex2(x * freq, y * freq)) * amplitude;
|
||||||
|
amplitude *= 0.35;
|
||||||
|
freq *= 2.0;
|
||||||
|
}
|
||||||
|
return clampNumber(value, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Domain Warping for FBM
|
||||||
|
* @param {Noise} noiseRef
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
* @param {Number} strength
|
||||||
|
* @param {Number} octaves
|
||||||
|
*/
|
||||||
|
export function DWFBMSimplex2(noiseRef, x, y, strength, octaves = 8)
|
||||||
|
{
|
||||||
|
let q = [FBMSimplex2(noiseRef, octaves, x, y), FBMSimplex2(noiseRef, octaves, x + 5.2, y + 1.3)];
|
||||||
|
return FBMSimplex2(noiseRef, octaves, x + q[0]*strength, y + q[1]*strength);
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
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<Number>}
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
import { Rectangle } from "../../../pixi/pixi.mjs";
|
||||||
|
|
||||||
|
class _type_TerrainTilesMapPreDefinition
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @type {Array<Rectangle>}
|
||||||
|
*/
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
};
|
@ -9,6 +9,8 @@ import { addGameObjectToGameState } from "../GameState/GameState";
|
|||||||
import { VegetationTile, VegetationTileProps } from "./WorldObjects/VegetationTile/VegetationTile";
|
import { VegetationTile, VegetationTileProps } from "./WorldObjects/VegetationTile/VegetationTile";
|
||||||
import { WorldChunksVisibilityUpdater } from "./WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater";
|
import { WorldChunksVisibilityUpdater } from "./WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater";
|
||||||
import { NavigationGridChunk, NavigationGridTile } from "../World/NavigationGrid/NavigationGrid";
|
import { NavigationGridChunk, NavigationGridTile } from "../World/NavigationGrid/NavigationGrid";
|
||||||
|
import { genTerrain } from "./TerrainGenerator/TerrainGenerator";
|
||||||
|
import { TerrainTilesMapPreDefinition } from "./TerrainPredefines/TerrainPredefines";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type Map<String, WorldChunk>
|
* @type Map<String, WorldChunk>
|
||||||
@ -18,9 +20,9 @@ const WorldChunksStorage = new Map();
|
|||||||
/* #### REWRITE PART START ####*/
|
/* #### REWRITE PART START ####*/
|
||||||
const terrainSpriteList = {
|
const terrainSpriteList = {
|
||||||
0: { x: 20, y: 20 }, //water
|
0: { x: 20, y: 20 }, //water
|
||||||
1: { x: 2, y: 20 }, //sand
|
1: { x: 0, y: 20 }, //sand
|
||||||
2: { x: 2, y: 2 }, //grass
|
2: { x: 0, y: 0 }, //grass
|
||||||
3: { x: 20, y: 2 }, //stone
|
3: { x: 20, y: 0 }, //stone
|
||||||
};
|
};
|
||||||
const terrainTypeList = {
|
const terrainTypeList = {
|
||||||
0: "ter_water", //water
|
0: "ter_water", //water
|
||||||
@ -29,7 +31,7 @@ const terrainTypeList = {
|
|||||||
3: "ter_stone", //stone
|
3: "ter_stone", //stone
|
||||||
};
|
};
|
||||||
const terrainNavigationCostList = {
|
const terrainNavigationCostList = {
|
||||||
0: 100000000000, //water
|
0: 10, //water
|
||||||
1: 1.7, //sand
|
1: 1.7, //sand
|
||||||
2: 1, //grass
|
2: 1, //grass
|
||||||
3: 1.5, //stone
|
3: 1.5, //stone
|
||||||
@ -147,8 +149,8 @@ let noise = new Noise(Math.floor(PRNG() * 188822321));
|
|||||||
let noiseErosion = new Noise(Math.floor(PRNG() * 327749029));
|
let noiseErosion = new Noise(Math.floor(PRNG() * 327749029));
|
||||||
let noiseBiomes = new Noise(Math.floor(PRNG() * 927472011));
|
let noiseBiomes = new Noise(Math.floor(PRNG() * 927472011));
|
||||||
|
|
||||||
let terrainCue = new NumberCue([0, 1, 2, 3, 3], [0.0, 0.2, 0.25, 0.9, 1.0]);
|
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.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.1]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -159,25 +161,30 @@ let terrainTintCue = new NumberCue([0.9, 1, 1, 0.95, 0.9, 1, 0.93, 1], [0.0, 0.4
|
|||||||
export function fillWorldGenChunk(chunk, x, y) {
|
export function fillWorldGenChunk(chunk, x, y) {
|
||||||
let ii = 0;
|
let ii = 0;
|
||||||
let jj = 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++) {
|
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.025, j * 0.025) + 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 res;
|
||||||
let resB = (noiseBiomes.simplex2(i * 0.01, j * 0.01) + 1) / 2;
|
res = terrainData[ii * BC_CHUNKS_SETTINGS.width + jj];
|
||||||
if (resB > 0.7) {
|
// let resR = (noiseErosion.simplex2(i * 0.3, j * 0.3) + 1) / 2;
|
||||||
res = clampNumber(res - resR / 4, 0.0, 0.99);
|
// let resB = (noiseBiomes.simplex2(i * 0.01, j * 0.01) + 1) / 2;
|
||||||
}
|
// if (resB > 0.7) {
|
||||||
if (resB > 0.5 && res < 0.9 && res >= 0.5) {
|
// res = clampNumber(res - resR / 4, 0.0, 0.99);
|
||||||
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();
|
let sTint = new RGBColor(255, 255, 255).multiplyByNumber(terrainTintCue.getValueAt(res)).toNumber();
|
||||||
res = Math.floor(terrainCue.getValueAt(res));
|
res = Math.floor(terrainCue.getValueAt(res));
|
||||||
|
|
||||||
let terrainTile = new TerrainTile(false);
|
let terrainTile = new TerrainTile(false);
|
||||||
terrainTile.spriteSheetPath = "assets/images/world/world_terrain_atlas.png";
|
let tilePreDefines = TerrainTilesMapPreDefinition[res];
|
||||||
terrainTile.frame = new Rectangle(terrainSpriteList[res].x, terrainSpriteList[res].y, 16, 16);
|
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.props = new TerrainTileProps(terrainTypeList[res], res * 5, terrainNavigationCostList[res]);
|
||||||
terrainTile.worldPosition = new Point2D(
|
terrainTile.worldPosition = new Point2D(
|
||||||
i * BC_TERRAIN_SETTINGS.scale * BC_TERRAIN_SETTINGS.tileSize,
|
i * BC_TERRAIN_SETTINGS.scale * BC_TERRAIN_SETTINGS.tileSize,
|
||||||
@ -187,8 +194,9 @@ export function fillWorldGenChunk(chunk, x, y) {
|
|||||||
addGameObjectToGameState(terrainTile);
|
addGameObjectToGameState(terrainTile);
|
||||||
|
|
||||||
terrainTile.drawObject.tint = sTint;
|
terrainTile.drawObject.tint = sTint;
|
||||||
terrainTile.drawObject.zIndex = 1;
|
terrainTile.drawObject.zIndex = 1 + tilePreDefines.zIndex;
|
||||||
terrainTile.drawObject.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
// 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);
|
terrainTile.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
||||||
|
|
||||||
chunk.addToChunk(terrainTile, ChunkStorageTypes.TYPE_TERRAIN, ii + "_" + jj);
|
chunk.addToChunk(terrainTile, ChunkStorageTypes.TYPE_TERRAIN, ii + "_" + jj);
|
||||||
@ -218,7 +226,7 @@ export function fillWorldGenChunk(chunk, x, y) {
|
|||||||
addGameObjectToGameState(vegetationTile);
|
addGameObjectToGameState(vegetationTile);
|
||||||
|
|
||||||
vegetationTile.drawObject.tint = sTint;
|
vegetationTile.drawObject.tint = sTint;
|
||||||
vegetationTile.drawObject.zIndex = 2;
|
vegetationTile.drawObject.zIndex = 10;
|
||||||
vegetationTile.drawObject.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
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);
|
vegetationTile.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user