类以撒的结合的房间生成算法
目前本人只实现了房间大小都一样的情况,没有什么2x2,L型,2x1之类的房间
放个效果图
算法需要注意的
房间选择
- 对于当前位置是否有设置房间(是否被占位)
- 当前房间位置是否越界(超出限定范围)
- 当前位置的周围4方向的房间量是否大于1个(为什么是1而不是0,因为那一个1是父节点,可以排除掉)
- 随机一个概率要是以上都满足可以设定一个概率是否抛弃
以下代码是基于在Unity上实现的,也有注释,应该很好理解
using System.Collections.Generic;
using UnityEngine;
//************************************
//创建人:一个人心
//功能说明:地牢生成
//************************************
public class DungeonGeneration : MonoBehaviour {
public GameObject RoomPref;
public Transform RoomParent;
private SpriteRenderer[] Rooms = new SpriteRenderer[100];
private int[] floorplan = new int[100];
private Queue<int> cellQueue = new Queue<int>(); // 所有已放置的房间
private Queue<int> endRoom = new Queue<int>(); // 末尾房间
private int startRoom = 35;
public int level = 1;
public int currentfloorPlan;
public int maxfloorPlan;
private void Awake() {
// 初始化地图
for (int i = 0; i < Rooms.Length; i++) {
floorplan[i] = 0;
var go = Instantiate(RoomPref, RoomParent);
go.transform.localPosition = new Vector3(i % 10, i / 10, 0);
Rooms[i] = go.GetComponent<SpriteRenderer>();
Rooms[i].color = Color.black;
}
}
[ContextMenu("生成地牢")]
private void BuildRangeRoom() {
// 初始化
currentfloorPlan = 0;
maxfloorPlan = (int)(Random.Range(0, 2) + 5 + level * 2.6);
cellQueue.Clear();
endRoom.Clear();
for (int i = 0; i < Rooms.Length; i++) {
floorplan[i] = 0;
Rooms[i].color = Color.black; // 设置黑色表示是墙 or 空位置
}
// 将开始房间入
visit(startRoom);
Rooms[startRoom].color = Color.yellow;
while (cellQueue.Count > 0) {
int i = cellQueue.Dequeue();
int x = i % 10;
bool create = false; // 标记当前房间是否有扩展出来的房间
if (x > 1) create = create | visit(i - 1);
if (x < 9) create = create | visit(i + 1);
if (i >= 10) create = create | visit(i - 10);
if (i < 90) create = create | visit(i + 10);
// 如果当前房间周围都不放置(i房间是末尾房)
// 末尾房可以设置一些特殊房间,因为末尾房是离起点远的房间
if (!create && i != startRoom) {
endRoom.Enqueue(i);
Rooms[i].color = Color.red;
}
// 当生成的房间数量大于一定时,可以将起点重写传回去
// 可以激励中心不会那么零散
if (currentfloorPlan > 16) {
if (Random.value < 0.25) {
Debug.Log("startRoom");
cellQueue.Enqueue(startRoom);
}
}
}
// 不合法
if (currentfloorPlan == 1) BuildRangeRoom();
}
/// <summary>
/// 检测是否可行
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
private bool visit(int i) {
// 检测当前放置的房间是否已经超出了
if (currentfloorPlan >= maxfloorPlan) return false;
// 检测是否被占用
if (floorplan[i] != 0) return false;
// 50%舍去
if (Random.value < 0.5 && i != startRoom) return false;
// 如果邻居数量大于1,因为1是之前的
if (nCount(i) > 1) return false;
// 可行
cellQueue.Enqueue(i); // 添加到已放置队列
floorplan[i] = 1; // 标记占用
currentfloorPlan++; // 总数++
Rooms[i].color = Color.white;
return true;
}
/// <summary>
/// 检测周围邻居数
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
private int nCount(int i) {
int sum = 0;
if (i + 10 < 100) sum += floorplan[i + 10];
if (i - 10 >= 0) sum += floorplan[i - 10];
if (i % 10 + 1 <= 9) sum += floorplan[i + 1];
if (i % 10 - 1 >= 0) sum += floorplan[i - 1];
return sum;
}
}
标签:10,int,create,房间,private,生成,算法,Rooms,类以
From: https://www.cnblogs.com/onepeopleheart/p/18059559