如何在Pygame中生成Perlin噪声实现岛屿、河流类自然地形效果?
问题分析
你当前代码生成的是完全随机的离散值,每个格子的地形类型和周边格子无任何关联,所以会出现杂乱的草地水域排布效果,和Perlin噪声连续地形的实现目标完全不相关:你现有代码中没有任何Perlin噪声的采样逻辑。
你当前得到的效果如下:
解决方案
首先安装Perlin噪声处理库:
pip install noise
之后替换原有的随机地图生成逻辑,通过坐标采样Perlin噪声的连续值,再通过阈值划分草地和水域即可得到自然连续的岛屿、河流地形。
修改后完整代码
#SetUp# import pygame, sys, random, noise pygame.init() win = pygame.display.set_mode((800, 600)) pygame.display.set_caption('Isom') x = 0 y = 0 s = 0 tilel = list() # 地形生成参数 SEED = 5843 SCALE = 30.0 # 地形缩放系数,值越大地形越平缓 THRESHOLD = 0.2 # 水域阈值,值越大水域占比越高 OCTAVES = 3 # 地形细节层数,值越大细节越多 # 初始化随机种子和噪声种子 random.seed(SEED) noise.seed(SEED) # 生成Perlin噪声地形 MAP = [] for a in range(12): for b in range(16): # 对当前坐标采样Perlin噪声值 noise_val = noise.pnoise2( b/SCALE, a/SCALE, octaves=OCTAVES, persistence=0.5, lacunarity=2.0, repeatx=1024, repeaty=1024, base=0 ) # 小于阈值为水,否则为草 MAP.append(1 if noise_val < THRESHOLD else 0) #Tiles# class tile(): grass = pygame.image.load('Sprites/Images/Grass.png') water = pygame.image.load('Sprites/Images/Water.png') #Loop# while True: for key in pygame.event.get(): if key.type == pygame.QUIT: pygame.quit() sys.exit() #World# for a in range(12): for b in range(16): if MAP[s] == 0: win.blit((tile.grass), (x, y)) elif MAP[s] == 1: win.blit((tile.water), (x, y)) x += 50 s += 1 x = 0 y += 50 x = 0 y = 0 s = 0 #Update# pygame.display.update()
参数调整说明
- 调整
SCALE数值:数值越大,岛屿、河流的面积越大,地形过渡越平缓;数值越小地形越破碎,小地块越多 - 调整
THRESHOLD数值:数值越大水域占比越高,岛屿越小;数值越小草地占比越高 - 调整
OCTAVES数值:数值越大地形的细节(小凸起、细小河流)越多,计算耗时也会略有上升 - 调整
SEED数值:可以生成完全不同的地图,相同SEED值会得到完全一致的地形效果
内容的提问来源于stack exchange,提问作者Pydude
相关产品推荐
相关产品推荐

