Add biomes generation
This commit is contained in:
parent
e7f1198499
commit
e83d5323a6
9
survival/biomes/biome_data.py
Normal file
9
survival/biomes/biome_data.py
Normal file
@ -0,0 +1,9 @@
|
||||
from survival.biomes.biome_preset import BiomePreset
|
||||
|
||||
|
||||
class BiomeData:
|
||||
def __init__(self, preset: BiomePreset):
|
||||
self.biome = preset
|
||||
|
||||
def get_diff_value(self, height: float, moisture: float, heat: float):
|
||||
return (height - self.biome.min_height) + (moisture - self.biome.min_moisture) + (heat - self.biome.min_heat)
|
22
survival/biomes/biome_preset.py
Normal file
22
survival/biomes/biome_preset.py
Normal file
@ -0,0 +1,22 @@
|
||||
import random
|
||||
|
||||
from survival.tile import Tile
|
||||
|
||||
|
||||
class BiomePreset:
|
||||
def __init__(self, name, min_height: float, min_moisture: float, min_heat: float, tiles: list[Tile]):
|
||||
self.name = name
|
||||
self.min_height = min_height
|
||||
self.min_moisture = min_moisture
|
||||
self.min_heat = min_heat
|
||||
self.tiles = tiles
|
||||
|
||||
def get_new_tile(self):
|
||||
tile = random.choice(self.tiles)
|
||||
return Tile(origin=tile.origin, cost=tile.cost, biome=self)
|
||||
|
||||
def get_tile_sprite(self):
|
||||
pass
|
||||
|
||||
def match_conditions(self, height, moisture, heat):
|
||||
return height >= self.min_height and moisture >= self.min_moisture and heat >= self.min_heat
|
6
survival/biomes/noise.py
Normal file
6
survival/biomes/noise.py
Normal file
@ -0,0 +1,6 @@
|
||||
from perlin_noise import PerlinNoise
|
||||
|
||||
|
||||
def generate_noise(width: int, height: int, octaves, seed):
|
||||
noise_map = PerlinNoise(octaves=octaves, seed=seed)
|
||||
return [[noise_map([x / width, y / height]) for y in range(width)] for x in range(height)]
|
@ -1,19 +1,70 @@
|
||||
import random
|
||||
|
||||
from survival.biomes.biome_data import BiomeData
|
||||
from survival.biomes.biome_preset import BiomePreset
|
||||
from survival.biomes.noise import generate_noise
|
||||
from survival.tile import Tile
|
||||
|
||||
|
||||
class TileGenerator:
|
||||
templates = [
|
||||
[(0, 0), 1], # Grass 1
|
||||
[(32, 0), 1], # Grass 2
|
||||
[(64, 0), 1], # Grass 3
|
||||
[(96, 0), 1], # Grass 4
|
||||
[(64, 64), 20], # Sand
|
||||
[(96, 64), 20], # Puddle
|
||||
Tiles = {
|
||||
"Grass1": Tile(origin=(0, 0), cost=1),
|
||||
"Grass2": Tile(origin=(32, 0), cost=1),
|
||||
"Grass3": Tile(origin=(64, 0), cost=1),
|
||||
"Grass4": Tile(origin=(96, 0), cost=1),
|
||||
"Sand": Tile(origin=(64, 64), cost=20),
|
||||
"Puddle": Tile(origin=(96, 64), cost=20),
|
||||
}
|
||||
|
||||
TilesValues = list(Tiles.values())
|
||||
|
||||
Biomes = [
|
||||
BiomePreset("Desert", min_height=0.2, min_moisture=0, min_heat=0.5, tiles=[Tiles["Grass1"], Tiles["Grass2"],
|
||||
Tiles["Grass3"], Tiles["Grass4"]]),
|
||||
BiomePreset("Grassland", min_height=0.2, min_moisture=0.5, min_heat=0.3, tiles=[Tiles["Sand"]]),
|
||||
BiomePreset("Marsh", min_height=0.1, min_moisture=0.6, min_heat=0.2, tiles=[Tiles["Puddle"]])
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_random_tile():
|
||||
template = random.choice(TileGenerator.templates)
|
||||
return Tile(template[0], template[1])
|
||||
tile = random.choice(TileGenerator.TilesValues)
|
||||
return Tile(origin=tile.origin, cost=tile.cost)
|
||||
|
||||
@staticmethod
|
||||
def generate_random_tiles(width: int, height: int) -> list[list[Tile]]:
|
||||
return [[TileGenerator.get_random_tile() for _ in range(width)] for _ in range(height)]
|
||||
|
||||
@staticmethod
|
||||
def generate_biome_tiles(width: int, height: int):
|
||||
seed = random.randint(0, 9999999)
|
||||
octaves = 10
|
||||
height_map = generate_noise(width, height, octaves, seed)
|
||||
moisture_map = generate_noise(width, height, octaves, seed)
|
||||
heat_map = generate_noise(width, height, octaves, seed)
|
||||
|
||||
return [[TileGenerator.get_biome(height_map[y][x], moisture_map[y][x], heat_map[y][x]).get_new_tile() for x in
|
||||
range(width)] for y in range(height)]
|
||||
|
||||
@staticmethod
|
||||
def get_biome(height, moisture, heat) -> BiomePreset:
|
||||
matching_biomes = list()
|
||||
|
||||
for biome in TileGenerator.Biomes:
|
||||
if biome.match_conditions(height, moisture, heat):
|
||||
matching_biomes.append(BiomeData(biome))
|
||||
|
||||
current_value = 0
|
||||
found_biome = None
|
||||
|
||||
for biome in matching_biomes:
|
||||
if found_biome is None:
|
||||
found_biome = biome.biome
|
||||
current_value = biome.get_diff_value(height, moisture, heat)
|
||||
elif biome.get_diff_value(height, moisture, heat) < current_value:
|
||||
found_biome = biome.biome
|
||||
current_value = biome.get_diff_value(height, moisture, heat)
|
||||
|
||||
if found_biome is None:
|
||||
found_biome = TileGenerator.Biomes[0]
|
||||
|
||||
return found_biome
|
||||
|
@ -1,5 +1,6 @@
|
||||
class Tile:
|
||||
def __init__(self, origin, cost):
|
||||
def __init__(self, origin: tuple = (0, 0), cost: int = 1, biome=None):
|
||||
self.origin = origin
|
||||
self.cost = cost
|
||||
self.biome = biome
|
||||
self.image = None
|
||||
|
@ -1,12 +1,14 @@
|
||||
from survival.image import Image
|
||||
from survival.generators.tile_generator import TileGenerator
|
||||
from survival.tile import Tile
|
||||
|
||||
|
||||
class TileLayer:
|
||||
def __init__(self, width, height):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.tiles = [[TileGenerator.get_random_tile() for x in range(self.width)] for y in range(self.height)]
|
||||
self.tiles: list[list[Tile]] = TileGenerator.generate_biome_tiles(width, height)
|
||||
# self.tiles: list[list[Tile]] = TileGenerator.generate_random_tiles(width, height)
|
||||
self.image = Image('atlas.png')
|
||||
|
||||
def draw(self, camera, visible_area):
|
||||
|
Loading…
Reference in New Issue
Block a user