79 lines
3.1 KiB
Python
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 |