project/generation_landwater.py

79 lines
3.1 KiB
Python

import numpy as np
import opensimplex
import random
class WorldGenerator:
def __init__(self, width=200, height=200, seed=None):
self.width = width
self.height = height
self.seed = seed if seed is not None else random.randint(0, 1000000)
self.noise = opensimplex.OpenSimplex(seed=self.seed)
random.seed(self.seed)
def generate_land_only(self):
return np.ones((self.height, self.width))
def generate_continent(self, size=0.7, roughness=0.5):
world = np.zeros((self.height, self.width))
center_x, center_y = self.width//2, self.height//2
for y in range(self.height):
for x in range(self.width):
nx = (x - center_x) / (self.width * 0.8)
ny = (y - center_y) / (self.height * 0.8)
dist = np.sqrt(nx**2 + ny**2) * (1.0/size)
noise_val = self.noise.noise2(x * roughness/10, y * roughness/10)
world[y][x] = 1 if (1 - dist) + noise_val * 0.5 > 0.4 else 0
return world
def generate_islands(self, density=0.6, island_size=0.3, roughness=0.5):
world = np.zeros((self.height, self.width))
scale = 20 / (island_size + 0.1)
temp_map = np.zeros((self.height, self.width))
for y in range(self.height):
for x in range(self.width):
nx = x / scale * (1 + roughness)
ny = y / scale * (1 + roughness)
noise_val = self.noise.noise2(nx, ny)
threshold = 0.5 - density*0.4
if noise_val > threshold:
temp_map[y][x] = 1
islands = []
visited = np.zeros_like(temp_map)
for y in range(self.height):
for x in range(self.width):
if temp_map[y][x] == 1 and visited[y][x] == 0:
island = []
queue = [(y, x)]
visited[y][x] = 1
min_y, max_y = y, y
min_x, max_x = x, x
while queue:
cy, cx = queue.pop()
island.append((cy, cx))
min_y = min(min_y, cy)
max_y = max(max_y, cy)
min_x = min(min_x, cx)
max_x = max(max_x, cx)
for dy, dx in [(-1,0),(1,0),(0,-1),(0,1)]:
ny, nx = cy+dy, cx+dx
if (0 <= ny < self.height and 0 <= nx < self.width and
temp_map[ny][nx] == 1 and visited[ny][nx] == 0):
visited[ny][nx] = 1
queue.append((ny, nx))
if (min_y > 0 and max_y < self.height-1 and
min_x > 0 and max_x < self.width-1):
islands.append(island)
for island in islands:
for y, x in island:
world[y][x] = 1
return world