最近几日闲来无事,后来看到了RogueLike的游戏,就像来试一下地牢生成算法。
网上看到了一篇文章写的挺好的。后面会有转载,不急哈。
先看一下我实现的效果图
生成过程:
地牢生成算法的思路是:
1.生成大量随机位置随机大小的房间2.通过物理碰撞将房间分散开3.通过阈值选取主要的房间4.对主房间进行三角剖分运算,得到房间之间的可选路径5.使用最小生成树选定房间之间的路径,并且保留少量回圈6.确定房间路路线7.路上经过的房间划入次要房间中8.绘制房间和路线.
随机生成房间
需要随机生成房间的初始位置,以及房间的长宽高
文章中提供了一种思路,在圆形中随机确定一个点,作为房间的初始位置。
而如何在圆形中随机生成一个点。
圆中生成随机点
先从一个三角形中入手
假设三角形ABC 且|AB| =|AC|。
在AB中找一个点X,在AC中找一个点Y,并用AX和AY做一个平行四边形XAYZ。那么这个随机点Z就找到了。
那万一Z超出了三角形呢
没事,超出了三角形,就将点Z以BC翻折到三角形中。
那我们该怎么运用在圆中呢?
其实这里去了一个极限,将一个圆细分成无数的等腰三角形
这样,我们只要在圆中选择一个三角形,再从三角形中随机选择一个点。
这样就能随机生成一个点了。
现在轮到房间大小了
房间大小可以利用上面的方法,在圆内生成一个点,再用这个点生成一个矩形。
可以有两种生成方法,如下图。
分散房间
这里可以选择使用Unity中自带的Rigidbody分散,
因为Unity的碰撞不好控制,常常跑出来一堆小数,所以我选择自己写一个Rigidbody。
逻辑非常简单,只需要判断自己是否覆盖别人的房间,如果覆盖就移动到没有覆盖。
移动距离计算
假设房间1 和房间2发生碰撞,
对于房间1
Offset= pos1-pos2
如果选择竖直方向的移动
需要判断是向上还是向下
方向:dirY= offsetY>0?1:-1;
距离:dis= y1/2+y2/2– abs(offsetY)
pos1+= vector2.up*dirY*dis
水平方向移动同理。
然后在FixUpdate中调用Simualeting。
筛选主房间
这里没什么好说的了,就是这个筛选房间可以在碰撞之前进行。