import alea from 'alea'; import {createNoise2D} from 'simplex-noise'; import {createRandom, Generator} from '@/util/math.js'; const seed = 42069; const prng = alea(seed); const rawNoise = createNoise2D(prng); const noise = (x, y) => (1 + rawNoise(x, y)) / 2; const random = createRandom(seed); const indexComputer = (indices, randomizer) => ( (position) => indices[Math.floor(indices.length * randomizer(position))] ); const [w, h] = [256, 256]; const Forest = new Generator({ calculate: indexComputer( [1, 3, 4, 10, 11, 12], // grass ({x, y}) => noise(x * 30, y * 30), ), covers: () => true, size: {w, h}, children: [ new Generator({ calculate: indexComputer( [342, 456], // dirt ({x, y}) => noise(x * 30, y * 30), ), covers: ({x, y}) => noise(x * (1 / 16), y * (1 / 16)) < 0.5, size: {w, h}, children: [ new Generator({ calculate: indexComputer( [407, 408, 423, 424], // stone path ({x, y}) => noise(x * 30, y * 30), ), covers: ({x, y}) => noise(x * (1 / 16), y * (1 / 16)) < 0.1625, size: {w, h}, }), ], }), new Generator({ calculate: indexComputer( [103, 104], // water ({x, y}) => noise(x * 30, y * 30), ), covers: ({x, y}) => noise(x * (1 / 32), y * (1 / 32)) < 0.3, size: {w, h}, }), ], }); export default async function createForest() { const area = {x: w, y: h}; const entities = []; entities.push({ AreaSize: {x: area.x * 16, y: area.y * 16}, Ticking: {}, TileLayers: { layers: [ { area, data: Array(w * h).fill(0), source: '/assets/tileset.json', tileSize: {x: 16, y: 16}, }, { area, data: Array(w * h).fill(0), source: '/assets/tileset.json', tileSize: {x: 16, y: 16}, }, ], }, Time: {}, Water: {}, }); Forest.generate(); const master = entities[0]; const layer0 = master.TileLayers.layers[0]; layer0.data = Forest.matrix; for (let y = 0; y < h; ++y) { for (let x = 0; x < w; ++x) { const dirt = Forest.children[0].matrix[y * w + x]; if (dirt) { layer0.data[y * w + x] = dirt; } const stone = Forest.children[0].children[0].matrix[y * w + x]; if (stone) { layer0.data[y * w + x] = stone; } const water = Forest.children[1].matrix[y * w + x]; if (water) { layer0.data[y * w + x] = water; } } } const entityPosition = (x, y) => ({ x: (8 + (x * 16) + random() * 8 - 4), y: (8 + (y * 16) + random() * 8 - 4), }); for (let y = 0; y < h; ++y) { for (let x = 0; x < w; ++x) { let v = noise(x * (1 / 24), y * (1 / 24)); if (v > 0.2) { v = noise(x * (1 / 7), y * (1 / 7)); if (v < 0.15) { entities.push({ Position: entityPosition(x, y), Sprite: { anchorY: 0.7, source: '/assets/ambient/shrub.json', }, VisibleAabb: {}, }); } else if (v < 0.17) { entities.push({ Position: entityPosition(x, y), Sprite: { anchorY: 0.875, source: '/assets/ambient/tree.json', }, VisibleAabb: {}, }); } v = noise(x * (1 / 12), y * (1 / 12)); if (v < 0.08) { entities.push({ Position: entityPosition(x, y), Sprite: { anchorY: 0.7, source: '/assets/ambient/flower.json', }, VisibleAabb: {}, }); } } } } return entities; }