看了网络上大多数生成2d随即地牢的教程,大多需要繁杂的公式和算法,做出来的结果一不一定尽如人意,于是我就想自己创作一个简单的,即随机地牢的生成。
下面是成品视频&图像
mapGenerator
接下来就由我来教大家如何实现这样的步骤。
第一步:下载素材
本次的素材为2D Pixel Dungeon Asset Pack by Pixel_Poem你可以在相关素材网站找到并下载,为后续的地牢制作提供丰富的视觉资源。
第二步: 新建项目
编辑器版本没有特别要求,只要支持 universal2D 模式即可。创建新项目时,确保选择 universal2D,为随机地牢的生成搭建好基础环境。
第三步:算法介绍和实现
要实现随即地牢的算法,我的思路是
1.初始化
创建一个Rooms(List<Vector2>)用于保存房间的坐标,第一个元素设置为(0, 0)
创建RoomCount(int) 用于保存房间数量,
2.随机方向以及可用方向检测
从(0, 0)开始,向随机四个地方游走。具体做法,先设置一个AllDirections(Vector2[]),用于保存所有方向。
private Vector2[] AllDirections = new Vector2[4]{
new Vector2(1, 0),
new Vector2(-1, 0),
new Vector2(0, 1),
new Vector2(0, -1)
};
然后检查当前坐标(不妨定义为StartPosition)是否包含于Rooms,如果包含,那么就删除这个方向。这样,我们就可以设计出以下函数,用于返回可以游走的方向。
private List<Vector2> CheckBlankDirections(Vector2 startPosition)
{
List<Vector2> blankDirections = new List<Vector2>();
for (int j = 0; j < 4; j++)
{
if (!rooms.Contains(startPosition + AllDirections[j]))
{
blankDirections.Add(AllDirections[j]);
}
}
return blankDirections;
}
3.生成所有房间坐标
3.1初始化-创建变量
创建Vector2 startPosition = new Vector2(0, 0);
List<Vector2> _rooms = new List<Vector2>();
_rooms.Add(startPosition);用于初始化。
3.2重复roomCount-1次,生成之后的房间
重复过程:
3.2.1 创建List<Vector2> blankDirections用于储存可用方向。
3.2.2 计算blankDirections的长度是否大于0,如果等于0(极小概率,恰好没有其他方向可以走,那么退出循环)如果大于0,继续
3.2.3 创建 Vector2 avalibleDirection = blankDirections[Random.Range(0, blankDirections.Count)];用于储存可用方向。
3.2.4 将newPosition = startPosition + avalibleDirection; 储存到_rooms里面。
3.3 返回_rooms _rooms是一个列表(List<Vector2>) 里面储存了每个房间的坐标。
3.4 代码呈现
private List<Vector2> GenerateRoutine(int roomCount){
Vector2 startPosition = new Vector2(0, 0);
List<Vector2> _rooms = new List<Vector2>();
_rooms.Add(startPosition); //初始化rooms
for (int i = 0; i < roomCount - 1; i++)
{
List<Vector2> blankDirections = CheckBlankDirections(startPosition); //计算可用方向
if (blankDirections.Count > 0){
Vector2 avalibleDirection = blankDirections[Random.Range(0, blankDirections.Count)];
Vector2 newPosition = startPosition + avalibleDirection;
_rooms.Add(newPosition);
startPosition = newPosition;
}
else{
Debug.Log("No more room");
break;
}
}
return _rooms;
}
第四步:创建ruleTile
按照方法创建ruleTile
切割素材并导入,按照图示