① [沙盒游戏][算法] 随机地图生成项目、一 柏林噪声的生成算法逻辑详细分析(Ken Perlin 源码)
沙盒游戏的魅力在于其无限的随机性和自由度,比如《我的世界》和《饥荒》等经典作品。作为开发者,对游戏中的随机性背后实现方式的好奇心驱使我们深入探究。作者计划通过Unity构建一个能生成类似《我的世界》地图的随机地图生成器,尽管更新可能因工作忙碌而较慢,但他欢迎同好们提出意见和建议。
这个系列的起点是作者的游戏启蒙——泰拉瑞亚,尽管它历经变迁,但柏林噪声生成算法成为了构建随机地图的关键。柏林噪声,实际上是通过梯度和线性插值,将随机数平滑连接,产生看起来自然的随机效果,通常使用Ken Perlin的函数实现。
柏林噪声的创造者Ken Perlin,一个在迪士尼电影《电子世界争霸战》中为特效开发出这种算法的传奇人物,其发明过程虽非传统科研团队的常规路径,却展现了个人的创造力。Ken Perlin于1982年就发明了柏林噪声,那时他还是哈佛大学的数学系本科生,这一成就令人惊叹。
详细讲解柏林噪声的生成逻辑,首先从网格划分开始,每个整数坐标点都有对应的随机梯度向量。这些梯度通过与距离向量的内积,通过线性插值确定点的最终值。虽然主流的插值函数是Ken Perlin建议的,但其他满足特定条件的函数也可用。他的源码基于java,虽然主要用于纹理生成,但对地图生成有一定启示。
总结柏林噪声的步骤:首先初始化网格,然后为每个整数点分配随机梯度,通过内积计算插值值。关键在于均匀的梯度选择,避免整体偏置,以提高随机性和效率。
在深入分析源码时,作者发现一些鲜为人知的问题,如梯度表的选择策略,以及固定梯度带来的随机性问题。此外,晶格顶点的特殊性也影响了地图生成的多样性和初始设置。虽然文章暂未深入可视化,但作者计划在后续内容中探讨这些话题。
② 三套简单的迷宫地图生成方案
文章基于一种基础的地图,来讨论三套不同的迷宫地图生成方案。不涉及代码,采用通俗语句和示意图说明生成方式,方案来源于游戏界前辈,根据自己的基础地图做了修正以适应不同游戏需要。生成后的地图可进一步丰富静态分布,增强地图表现。文章展示地图面积较小,便于表达迷宫生成规则,实际游戏制作时,按需扩展。
地图形式多样,使用tile块分割,主要分为三类:陆地、过渡、水域。其中水域作为分割元素,围绕陆地设计迷宫,过渡地块根据游戏需求生成。若不使用水域,可替换为传统墙壁。
方案一:主路扭曲型
1. 首先生成基础地图,用1表示陆地,0表示水域。
2. 选择靠近边缘的1作为起点,随机找另一个黄色1(上下左右方向)联通,将相邻0变为陆地。
3. 从新格子开始重复步骤2,直至找不到黄色1。
4. 按原路返回,找到有黄色1的格子开始循环,直至生成完整迷宫。
5. 迷宫生成后,添加终点完成。
此方案生成迷宫有一条贯穿大部分区域的扭曲主路。
方案二:自然分岔型
1. 生成基础地图,用1表示黄色1,0表示灰色0。
2. 随机选择边缘黄色1变为红色1(陆地),周围灰色0标记为蓝色0。
3. 随机选择蓝色0,检查对面红色1,若对面为黄色1,则将对面黄色1变为红色1,蓝色0变为红色0,更新周围灰色0为蓝色0。
4. 重复步骤3,直到地图无蓝色0。
此方案生成迷宫分岔路多,相对自然,但可能比前两种更复杂。
方案三:块状分割型
1. 在大地图上生成若干小型地块(奇数边长,不重合),用橙色1表示。
2. 依据方案一,在非地块区域生成迷宫,使迷宫与地块分开。
3. 随机连接地块周围黄色1,数量根据需求调整。
4. 简化地图,去掉3边为灰色0的黄色1,减少死胡同。
5. 添加入口和出口完成地图。
此方案增加小型地块,适合设计玩家反馈,分岔路减少,选择次数降低,便于控制地图结构。
所有方案在生成后,地图面积较小,适用于表达迷宫规则,实际游戏制作时需按需扩展。迷宫生成后,可进一步丰富静态分布,增强地图表现。方案选择基于游戏需求,不同方案生成的迷宫特征各异,适用于不同游戏场景。
参考资源包括随机prim算法的多种分析与实现,以及基于小型地块的迷宫生成思路。迷宫生成网页提供直观的生成工具,允许设定迷宫大小和形状规则。
③ 波函数坍缩 地图生成-算法过程可视化(2D)
波函数坍缩(Wave Function Collapse)生成 ,是一个随机程序化的生成算法,比较经典的是用在游戏场景的地图生成。想要了解详细的解读可以参考 《波函数坍缩算法》的无限城市... ,当前文章是WFC 2D版本的实现。
点击 查看可视化样例
这有一个可视化的程序,它可以 逐步、暂停 、回放 整个计算过程 ,以便于你理解 wfc 算法。
每个都对应地图上的一个确定坐标位置,初始状态,每个Slot 都包含成为任何一种图案(Model)可能性,这种可能性用"熵"来表示,经过坍缩最终成为一个确定的图案。
这里指的是信息熵,当值越大时,图案的可能性就越多,演示程序为了方便将展示"熵"值进行了单位化(范围 0-1)。
具体的图案,包含有:图片资源、旋转角度、权重值(概率)、四条边信息。
每条边都有connectId ,用于判断两条边是否能够相互连接。
波函数坍缩算法 2D 版本的实现。
github 链接 : https://github.com/anseyuyin/wfc2D
语言环境: typescript 、 javascript
项目包含了