Roguelike 开发小组

创建于:2016-04-16

创建人: eastecho

100 信息 1410 成员
Roguelike 开发的相关讨论

用Unity实现《随机生成 Tile Based 地图之——洞穴》中的算法(已更新)

jiangqi9090 2016-08-11

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);
}
}
}





Image title




近期喜欢的会员

 
craft 2016-08-11

有心了~ 可惜小组对代码显示的支持不是很友好,没有高亮和缩进。

 
BjChacha 2016-08-15

将代码分块讲解且适当加入注释会更好一些。

 

贴在gist上

 

加入 indienova

  • 建立个人/工作室档案
  • 建立开发中的游戏档案
  • 关注个人/工作室动态
  • 寻找合作伙伴共同开发
  • 寻求线上发行
  • 更多服务……
登录/注册