https://indienova.com/indie-game-development/procedural-content-generation-tile-based-random-cave-map/ 原文地址
只做了初始的部分,改进后由于周围墙的检测大了一圈,数组里判定边界太麻烦,也没想到好的方法就懒得写了。
把代码绑在场景中任意物体上,并手动指定cube1和cube2即可, R键初始化,F键迭代,可修改行数和列数。
仅供大家参考。
2016.8.12重新编辑:
用二维数组重写了代码,算法也使用了改进后的,但生成的地图四周有些不太平整。由于原文写的比较精简,经过我对原文以及原网页JS代码的理解只能写到这样,供大家参考。
using UnityEngine; using System.Collections; public class Script : MonoBehaviour { public int row = 30; public int col = 35; private bool[,] mapArray; public GameObject cube1, cube2; GameObject cubes; int times; int a; void Start () { cubes = new GameObject (); mapArray = InitMapArray (); CreateMap (mapArray); } void Update() { if (Input.GetKeyDown (KeyCode.R)) { Button1 (); } if (Input.GetKeyDown (KeyCode.F)) { Button2 (); } } bool[,] InitMapArray() { bool[,] array = new bool[row , col]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { array [i,j] = Random.Range (0, 100) < 60; if (i == 0 || i == row - 1 || j == 0 || j == col - 1) { array[i, j] = false; } } } return array; } bool[,] SmoothMapArray(bool[,] array) { bool[,] newArray = new bool[row , col]; int count1, count2; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { count1 = CheckNeighborWalls (array, i, j, 1); count2 = CheckNeighborWalls (array, i, j, 2); if (count1 >= 5 || count2 <= 2) { newArray [i, j] = false; } else { newArray [i, j] = true; } if (i == 0 || i == row - 1 || j == 0 || j == col - 1) { newArray [i, j] = false; } // newArray[i, j] = count1 >= 5 || count2 <= 2 ? true : false; } } return newArray; } int CheckNeighborWalls(bool[,] array, int i, int j ,int t) { int count = 0; for (int i2 = i - t; i2 < i + t + 1; i2++) { for (int j2 = j - t; j2 < j + t + 1; j2++) { if (i2 > 0 && i2 < row && j2 >= 0 && j2 < col) { if (!array[i2, j2]) { count++; } } } } if (!array[i, j]) count--; return count; } void CreateMap(bool[,] array) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (!array [i , j]) { GameObject go = Instantiate (cube1, new Vector3 (i, 1, j), Quaternion.identity)as GameObject; go.transform.SetParent (cubes.transform); } else { GameObject go = Instantiate (cube2, new Vector3 (i, 0, j), Quaternion.identity)as GameObject; go.transform.SetParent (cubes.transform); } } } } public void Button1() { times = 0; Destroy (cubes); cubes = new GameObject (); mapArray = InitMapArray (); CreateMap (mapArray); } public void Button2() { if (times < 7) { times++; Destroy(cubes); cubes = new GameObject(); mapArray = SmoothMapArray(mapArray); CreateMap(mapArray); } } }