using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Maze : MonoBehaviour
{
public GameObject[] wallPrefab; // 墙壁预制体
public GameObject[] pathPrefab; // 路径预制体
public GameObject stairsPrefab; // 梯子预制体
public GameObject treePrefab; // 树预制体
public int mazeWidth = 10; // 迷宫宽度
public int mazeHeight = 10; // 迷宫高度
public int mazeLayer = 3; // 迷宫层
public int layerHeight = 14; // 层高度
public int mazeStairsMax = 5; // 迷宫高度
public float cellSize = 10f; // 单元格大小
private int[][][] maze; // 迷宫二维数组
private void Start()
{
maze = new int[mazeLayer][][];
for (int l = 0; l < mazeLayer; l++)
{
maze[l] = creatMap(mazeWidth, mazeHeight);
}
AddStairs();
for (int l = 0; l < mazeLayer; l++)
{
GameObject la = new GameObject("la" + l);
la.transform.parent = transform;
for (int i = 1; i < maze[l].Length - 1; i++)
{
for (int j = 1; j < maze[l][i].Length - 1; j++)
{
switch (maze[l][i][j])
{
case 1:
if (l == 0)
{
bool cre = true;
for (int m = 1; m < mazeLayer; m++)
{
if (i < maze[m].Length && j < maze[m][i].Length && maze[m][i][j] != 1)
{
cre = false;
break;
}
}
if (cre)
{
GameObject wall = Instantiate(wallPrefab[Random.Range(0, wallPrefab.Length)], la.transform);
wall.transform.localPosition = new Vector3(i * cellSize, l * layerHeight, j * cellSize);
}
}
else
{
GameObject tree = Instantiate(treePrefab, la.transform);
tree.transform.localPosition = new Vector3(i * cellSize, l * layerHeight, j * cellSize);
}
break;
case 2:
GameObject stairs = Instantiate(stairsPrefab, la.transform);
stairs.transform.localPosition = new Vector3(i * cellSize, l * layerHeight, j * cellSize);
break;
case 3:
break;
default:
GameObject path = Instantiate(GetPath(i,l,j), la.transform);
path.transform.localPosition = new Vector3(i * cellSize, l * layerHeight, j * cellSize);
break;
}
}
}
}
//StaticBatchingUtility.Combine(gameObject);
}
public GameObject GetPath(int i,int l, int j)
{
if (maze[l][i][j - 1] == 0 && maze[l][i][j + 1] == 0 && (maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)) && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
{
// ┼
return pathPrefab[0];
}
else if (maze[l][i][j - 1] == 0 && maze[l][i][j + 1] == 0 && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
{
//├
return pathPrefab[1];
}
else if (maze[l][i][j - 1] == 0 && maze[l][i][j + 1] == 0 && (maze[l][i - 1][j] == 0 ||(l > 0 && maze[l - 1][i - 1][j] == 2)))
{
// ┤
return pathPrefab[2];
}
else if (maze[l][i][j - 1] == 0 && (maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)) && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
{
// ┴
return pathPrefab[3];
}
else if (maze[l][i][j + 1] == 0 && (maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)) && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
{
// ┬
return pathPrefab[4];
}
else if (maze[l][i][j + 1] == 0 && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
{
//└
return pathPrefab[5];
}
else if (maze[l][i][j - 1] == 0 && maze[l][i - 1][j] == 0)
{
//┌
return pathPrefab[6];
}
else if (maze[l][i][j - 1] == 0 && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
{
//┘
return pathPrefab[7];
}
else if (maze[l][i][j + 1] == 0 && (maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)))
{
//┐
return pathPrefab[8];
}
else if ( maze[l][i - 1][j] == 0 && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
{
//—
return pathPrefab[9];
}
else if (maze[l][i][j - 1] == 0 && maze[l][i][j + 1] == 0)
{
//│
return pathPrefab[10];
}
else if ((maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)))
{
//→
return pathPrefab[11];
}
else if (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2)
{
//←
return pathPrefab[12];
}
else if (maze[l][i][j - 1] == 0)
{
//↑
return pathPrefab[13];
}
else if (maze[l][i][j + 1] == 0)
{
//↓
return pathPrefab[14];
}
return pathPrefab[0];
}
public void AddStairs()
{
for (int l = 0; l < maze.Length - 1; l++)
{
List<Vector3Int> list = new List<Vector3Int>();
for (int i = 1; i < maze[l + 1].Length - 1; i++)
{
for (int j = 1; j < maze[l + 1][i].Length - 1; j++)
{
if (maze[l][i][j] == 1 && maze[l + 1][i][j] == 1 && maze[l][i - 1][j] == 0 && maze[l + 1][i + 1][j] == 0)
{
list.Add(new Vector3Int(l, i, j));
}
}
}
if (list.Count > mazeStairsMax)
{
for (int i = 0; i < mazeStairsMax; i++)
{
Vector3Int v3 = list[Random.Range(0, list.Count)];
maze[v3.x][v3.y][v3.z] = 2;
if (maze[0][v3.y][v3.z] == 1)
{
maze[0][v3.y][v3.z] = 3;
}
}
}
else
{
for (int i = 0; i < list.Count; i++)
{
Vector3Int v3 = list[i];
maze[v3.x][v3.y][v3.z] = 2;
}
}
}
}
int[][] mapArr;
List<int> notAccessed = new List<int>();
List<int> accessed = new List<int>();
int rand(int min, int max)
{
int num = Mathf.FloorToInt(Random.Range(min, max));
return num;
}
public int[][] creatMap(int r, int c)
{
notAccessed.Clear();
accessed.Clear();
mapArr = new int[2 * r + 1][];
for (int i = 0; i < mapArr.Length; i++)
{
mapArr[i] = new int[2 * c + 1];
for (int n = 0; n < mapArr[i].Length; n++)
{
if ((n ^ (n - 1)) == 1 && (i ^ (i - 1)) == 1)
{
mapArr[i][n] = 0; // 0 表示路
notAccessed.Add(0);
}
else
{
mapArr[i][n] = 1; // 1 表示墙
}
}
}
int count = r * c;
int cur = rand(0, count);
int[] offs = new int[] { -c, c, -1, 1 }; // 四周顶点在notAccessed的偏移量
int[] offr = new int[] { -1, 1, 0, 0 }; // 四周顶点在arr的纵向偏移量
int[] offc = new int[] { 0, 0, -1, 1 }; // 四周顶点在arr的横向偏移量
accessed.Add(cur);
notAccessed[cur] = 1;
while (accessed.Count < count)
{
int tr = Mathf.FloorToInt(cur / c);
int tc = cur % c;
int off = -1;
// 遍历上下左右顶点
for (int i = 0; i < 4; i++)
{
int around = rand(0, 4);
int nr = tr + offr[around];
int nc = tc + offc[around];
if (nr >= 0 && nc >= 0 && nr < r && nc < c && notAccessed[cur + offs[around]] == 0)
{
off = around;
break;
}
}
// 四周顶点均被访问,则从已访问的顶点中随机抽取一个为cur
if (off < 0)
{
cur = accessed[rand(0, accessed.Count)];
}
else
{
tr = 2 * tr + 1;
tc = 2 * tc + 1;
mapArr[tr + offr[off]][tc + offc[off]] = 0;
cur = cur + offs[off];
notAccessed[cur] = 1;
accessed.Add(cur);
}
}
return mapArr;
}
}
unity下多层随机迷宫构建
最新推荐文章于 2024-02-14 23:51:55 发布