gen-biome
Version:
Procedural generation of 2D maps with distinct biomes
64 lines (50 loc) • 1.66 kB
text/typescript
import { WorldBiome } from '../biome';
import type { WorldBiomeConfig } from '../biome/types';
import { Perlin } from '../utils/perlin';
import { Seed } from '../utils/seed';
import { World } from '../world';
import type { WorldConfig } from '../world/types';
import type { WorldGenerationParams } from './types';
export class WorldGenerator<T extends object> {
readonly config: WorldConfig;
private biomes: WorldBiome<T>[] = [];
constructor(config: WorldConfig) {
this.config = config;
}
public addBiome(config: WorldBiomeConfig, data: T): WorldBiome<T> {
const biome = new WorldBiome<T>(config, data);
this.biomes.push(biome);
return biome;
}
public clearBiomes(): void {
this.biomes = [];
}
public getBiomes(): WorldBiome<T>[] {
return this.biomes;
}
public peakBiome(height: number): WorldBiome<T> | null {
return this.getBiomes().find((biome) => (
height >= biome.lowerBound && height <= biome.upperBound
)) ?? null;
}
public generate(params?: WorldGenerationParams): World<T> {
const currentSeed = params?.seed ?? Seed.generate(params?.seedSize);
const matrix: T[][] = [];
for (let y = 0; y < this.config.height; y++) {
matrix[y] = [];
for (let x = 0; x < this.config.width; x++) {
const height = Perlin.generate({
config: this.config,
seed: currentSeed,
x: x + (params?.offsetX ?? 0),
y: y + (params?.offsetY ?? 0),
});
const biome = this.peakBiome(height);
if (biome) {
matrix[y][x] = biome.data;
}
}
}
return new World<T>(matrix, currentSeed);
}
}