图形引擎实战:随机关卡

起因

在游戏制作中,游戏的迭代更新对美术的压力一直是比较大的,有一些游戏的玩法需要不断的生成新的场景,而自动生成场景能在一定程度上缓解美术的压力。 运用随机场景生成比较典型的就是Roguelike的游戏类型,随机生成关卡,怪物,资源等。非Rougelike游戏引入随机地图也可以带来一些玩法上的丰富性。 这种随机性导致了玩家不能单纯地背板来通过关卡,而必须随机应变。

生成方法

TileBase 地形生成 都是用预先美术制作好的地图块通过算法来拼接成一个大型的地图。根据块的大小,又分为两个方向。

用小块来拼

* 优点 块的制作相对简单,生成的地图随机性较大,比较适合小规模场景

* 缺点 对于一些游戏类型(MMO),想要制作规模宏大的场景,小块的数量及设计也是一个噩梦

用大块来拼

* 优点 利用大块地形基本掩盖了随机的样式,通过美术的精心安排,可以达到较好的美术效果。

* 缺点 美术工作量相对巨大,但设计上相对简单

算法

波函数坍塌

至于什么是波函数坍塌可以参考下面的文章 《波函数坍塌》 - 知乎 摘录一段通俗易懂的描述

《The Wavefunction Collapse Algorithm explained very clearly》通过婚礼安排,和海岸线模拟给出了很好的解释,可以看看。
大致意思就是,你想象你在安排一个婚礼座位,即把所有嘉宾安排到合适的座位上,如果没有任何约束条件,那就有 N * M 中可能,但是加上约束条件(Rules),一个座位一个座位安排(Propagate 传播),以及失败之后重新来(回溯),就通过 WFC 实现了座位安排,其实听起来高大上的名词,大致就是这个意思(在量子力学之外的时候)。
其中还提到了计算 熵(entropy),一般熵用来表示复杂度,混乱程度(比如信息熵,热力学里的熵)。熵越低,越稳定,在这里 熵 就是可能性,可能性越高,随机的时候越可能选中。
比如安排座位的时候,通过各种约束后计算出来,A 右边是 B 的可能性是 30%,是 C 的可能性是 70%,那么大概率 A 旁边就会安排 C。

GitHub上有个非常有名的开源项目 无限城市

无限城市 https://github.com/marian42/wavefunctioncollapse

Tile的设计主要是注意边缘的衔接,我们的美术想到了一种很聪明的办法,使用世界坐标来计算uv,这样只要模型对的上,就不会有接缝的问题。

另外一个常见的问题就是路径Tile的设计,路径Tile的大小,出口方向,内部布局,配合上生成概率,对最终的结果都有比较大的影响。

在这个问题上,美术同学也设计了特殊的材质,通过mask及参数控制路径与草地的融合,这样只要替换两个layer的贴图就可以生成不同纹理的路径tile。

地宫

波函数坍塌也是可以坐地宫的,但并不是最合适的方法,地宫主要是由房间,及连接房间的过道形成的。 下面介绍一种更试用于地宫类型的方法。

1. 首先,我设置了我想要生成的单元格的数量,比如 150。这实际上是一个任意数量,但数字越大,地牢越大,通常越复杂。

2. 对于每个“单元格”,我在某个半径内生成一个随机宽度和长度的矩形。同样,半径并不重要,但它可能应该与单元格的数量成正比。我没有使用均匀分布的随机数(大多数语言中默认的 Math.random 生成器),而是使用Park-Miller Normal Distribution。这会扭曲单元格的大小,以便它们更可能是小尺寸(更小的单元格,更少的更大单元格)。后面会解释这个原因!除此之外,我确保每个单元格的宽度和长度之间的比率不会太大,我们不想要完美的方形房间,但我们也不想要非常瘦的房间,但介于两者之间。

3. 此时我们在一个小区域内有 150 个随机单元,大部分是重叠的。接下来,我们使用简单的分离转向行为来分离出所有的矩形,这样没有一个是重叠的。这种技术确保细胞不重叠,但通常尽可能紧密地挤在一起。

4. 我们用 1x1 大小的单元格填充任何空白。结果是我们最终得到了一个由不同大小的单元格组成的方形网格,所有单元格都完美地打包在一起。

5. 这是乐趣开始的地方。我们确定网格中的哪些单元格是房间 - 任何宽度和高度高于某个阈值的单元格都被制成房间。由于前面描述的 Park-Miller 正态分布,与单元的数量相比,只有少量的房间,并且之间有很多空间。剩余的单元格仍然有用,但是……请继续阅读。

6. 对于下一阶段,我们希望将每个房间连接在一起。首先,我们使用Delaunay Triangulation构建所有房间中心点的图形。所以现在所有房间都相互连接,没有相交的线。

7. 因为我们不希望每个房间都通过走廊相互连接(这会造成非常混乱的布局),所以我们使用前面的图构造了一个最小生成树。这将创建一个图表,保证所有房间都已连接(因此在游戏中可到达)。

8. 最小生成树看起来不错,但又是一个无聊的地牢布局,因为它不包含循环,它是 Delaunay 三角剖分的另一个极端。所以现在我们重新合并三角图中的少量边(比如创建最小生成树后剩余边的 15%)。因此,最终的布局将是所有房间的图表,每个房间都保证是可到达的,并且包含一些用于多样化的循环。

9. 为了将图形转换为走廊,我们为每条边构建一系列直线(或 L 形),从图形的每个房间到其邻居。这是我们尚未使用的单元格(网格中不是房间的单元格)变得有用的地方。任何与 L 形相交的单元格都成为走廊瓷砖。由于牢房大小不同,走廊的墙壁会曲折不平,非常适合地牢。

导航

地形有了,接下来就要考虑一个问题,寻路。以Unity引擎为例,其提供了runtime的Navmesh生成,对规模不是很大的地形生速度 还是很快的。而对于大规模地形,我们可以预先烘焙Tile的Navmesh,然后再多个navmesh之间进行寻路,可以参考我们的另外一个文章。或者runtime一次性只烘焙主角附近的Tile。具有导航信息的Tile一定不要勾选static。

对于服务器端的寻路情况稍微复杂一些:

客户端生成后上传到服务器,该方法服务器端接入工作量比较小,但是紧紧适用比较小的地形,navmesh还是比较大的,对流量不是很友好

服务器接入完整的生成流程,由服务器生成navmesh,服务器要接入地形生成,navmesh生成。

服务器预先保存每个Tile的navmesh,按照tile的生成方式拼合这些navmesh

总结

程序化的地形生成能够在有限的美术资源下生成富有变化的地形,同时生成的方法也是多种多样,根据游戏的类型,玩法,表现效果等综合考虑生成方法。

欢迎加入我们!

感兴趣的同学可以投递简历至:CYouEngine@cyou-inc.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搜狐畅游引擎部

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值