如果要想自己设计一个roguelike游戏,那么需要你有一个随机地图生成,我在indienova上看到一篇文章,描述了一个roguelike算法,然后自己用unity实现了一个下。

原文地址:随机生成 Tile Based 地图之——洞穴

原文有这个算法的各种讲解,还有动态的演示图,不理解算法原理的可以去看一下。

根据这个算法的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public enum Tile
{
Floor,//地板
Wall//墙
} public class createMap : MonoBehaviour { public int row = 30;
public int col = 30;
private Tile[,] mapArray;
public GameObject wall, floor,player;
private GameObject map;
private Transform maps;
private int forTimes=0;//SmoothMapArray循环次数
// Use this for initialization
void Start () {
mapArray = new Tile[row,col];
maps = GameObject.FindGameObjectWithTag ("map").transform;
map = new GameObject ();
map.transform.SetParent (maps);
//CreateMap (); GenerateMap ();
} // Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.Q)) {
Destroy (map);
GenerateMap ();
}
if (Input.GetKeyDown (KeyCode.W)) {
InitMap ();
}
//下一步
if (Input.GetKeyDown (KeyCode.E)) {
CreateMap ();
}
}
private void InitMapArray(){
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
//采用<50%生成墙
mapArray[i,j] = Random.Range(0,100)<40?Tile.Wall:Tile.Floor;
//边界置为墙
if (i == 0 || j == 0 || i == row - 1 || j == col - 1) {
mapArray [i, j] = Tile.Wall;
}
}
}
} private Tile[,] SmoothMapArray0(){
Tile[,] newMapArray = new Tile[row,col];
int wallCount1 = 0,wallCount2 = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
wallCount1 = CheckNeighborWalls (mapArray, i, j, 1);
wallCount2 = CheckNeighborWalls (mapArray, i, j, 2);
if (mapArray [i, j] == Tile.Wall) {
newMapArray [i, j] = (wallCount1 >= 4) ? Tile.Wall : Tile.Floor;
} else {
newMapArray [i, j] = (wallCount1 >= 5 || wallCount2<=2) ? Tile.Wall : Tile.Floor;
}
if (i == 0 || i == row - 1 || j == 0 || j == col - 1) {
newMapArray [i, j] = Tile.Wall;
}
}
}
return newMapArray;
} //4-5规则
//当前墙:周围超过4个保持为墙
//当前地板:周围超过5个墙变为墙
//循环4-5次
private Tile[,] SmoothMapArray1(){
Tile[,] newMapArray = new Tile[row,col];
int wallCount = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
wallCount = CheckNeighborWalls (mapArray, i, j, 1);
if (mapArray [i, j] == Tile.Wall) {
newMapArray [i, j] = (wallCount >= 4) ? Tile.Wall : Tile.Floor;
} else {
newMapArray [i, j] = (wallCount >= 5) ? Tile.Wall : Tile.Floor;
}
if (i == 0 || i == row - 1 || j == 0 || j == col - 1) {
newMapArray [i, j] = Tile.Wall;
}
}
}
return newMapArray;
} //判断周围墙的数量
private int CheckNeighborWalls(Tile[,] mapArray, int i,int j,int t){
int count = 0;
for (int k = i - t; k <= i + t; k++) {
for (int l = j - t; l <= j + t; l++) {
if (k >= 0 && k < row && l >= 0 && l < col) {
if (mapArray[k,l] == Tile.Wall) {
count++;
}
}
}
}
//去除本身是否为墙
if (mapArray[i,j] == Tile.Wall) {
count--;
}
return count;
} private void InstanceMap (){
bool setPlayer = true;
map = new GameObject ();
map.transform.SetParent (maps);
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (mapArray [i, j] == Tile.Floor) {
GameObject go = Instantiate (floor, new Vector3 (i, j, 1), Quaternion.identity) as GameObject;
go.transform.SetParent (map.transform);
//设置层级
go.layer = LayerMask.NameToLayer ("floor"); if (setPlayer) {
//设置角色
GameObject g_player = Instantiate (player, new Vector3 (i, j, 1), Quaternion.identity) as GameObject;
g_player.transform.SetParent (map.transform);
setPlayer = false;
}
} else if (mapArray [i, j] == Tile.Wall) {
GameObject go = Instantiate (wall, new Vector3 (i, j, 1), Quaternion.identity) as GameObject;
go.transform.SetParent (map.transform);
go.layer = LayerMask.NameToLayer ("wall");
}
}
}
} private void InitMap (){
forTimes = 0;
Destroy (map);
map = new GameObject ();
map.transform.SetParent (maps);
InitMapArray ();
InstanceMap ();
} private void CreateMap (){
Destroy (map);
map = new GameObject ();
map.transform.SetParent (maps);
if (forTimes < 7) {
if (forTimes < 4) {
mapArray = SmoothMapArray0 ();
} else {
mapArray = SmoothMapArray1 ();
}
forTimes++;
}
InstanceMap ();
} private void GenerateMap (){
forTimes = 0;
map = new GameObject ();
map.transform.SetParent (maps);
InitMapArray ();
while (forTimes < 7) {
if (forTimes < 4) {
mapArray = SmoothMapArray0 ();
} else {
mapArray = SmoothMapArray1 ();
}
forTimes++;
}
InstanceMap ();
} }
运行效果图:
最开始随机出来的地图,后面是逐步处理的效果:



roguelike地图的随机生成算法的更多相关文章

  1. 微信红包随机生成算法(PHP版)

    /** * 求一个数的平方 * @param $n */ function sqr($n){ return $n*$n; } /** * 生产min和max之间的随机数,但是概率不是平均的,从min到 ...

  2. roguelike地牢生成算法

    文章原地址 上一个地图生成算法,这一次是一个地牢的生成算法,是一个国外的人写的算法,用dart语言写,我把它改成了unity-c#. 原作者博客地址:Rooms and Mazes: A Proced ...

  3. Unity 随机地图房间通道生成

    之前的博客中已经说了随机房间生成: https://www.cnblogs.com/koshio0219/p/12604383.html 但实现房间生成只是整个地图生成最初最简单的一步.下面讨论如何随 ...

  4. 2D地图随机生成

    2D地图随机生成基础绘图 海陆分布

  5. 星际SC地图制作中生成随机位置,也包括所有需要随机的效果

    星际SC地图制作中生成随机位置,也包括所有需要随机的效果 利用单位 kakaru T 开头那个, kakaru是随机变化位置 注意kakaru的放置位置和占用格子大小,kakaru周围放上LOCATI ...

  6. SpriteKit游戏Delve随机生成地牢地图一个Bug的修复

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Delve是一个很有意思的地牢探险类型的游戏,其中每一关的地图 ...

  7. Book of Shaders 03 - 学习随机与噪声生成算法

    0x00 随机 我们不能预测天空中乌云的样子,因为它的纹理总是具有不可预测性.这种不可预测性叫做随机 (random). 在计算机图形学中,我们通常使用随机来模拟自然界中的噪声.如何获得一个随机值呢, ...

  8. 每日算法3:随机生成五个不同整数,将数字转换为RMB格式

    随机生成五个不同整数 点击查看代码 /* 题目解析: 1.采用Math对象的random()方法, 2.将每次生成的数跟之前的数判断相等则此次生成无效i-- */ function randomNum ...

  9. Bagging与随机森林算法原理小结

    在集成学习原理小结中,我们讲到了集成学习有两个流派,一个是boosting派系,它的特点是各个弱学习器之间有依赖关系.另一种是bagging流派,它的特点是各个弱学习器之间没有依赖关系,可以并行拟合. ...

随机推荐

  1. iOS开发 - UIViewController控制器管理

    创建一个控制器 控制器常见的创建方式有下面几种 //通过storyboard创建 //直接创建 ViewController *vc = [[ViewController alloc] init]; ...

  2. java中的File文件读写操作

    之前有好几次碰到文件操作方面的问题,大都由于时间太赶而没有好好花时间去细致的研究研究.每次都是在百度或者博客或者论坛里面參照着大牛们写的步骤照搬过来,之后再次碰到又忘记了.刚好今天比較清闲.于是就在网 ...

  3. 设置netbeans文件编码格式

    在项目ecmall上右键 选择属性,然后在项目属性里设置

  4. EasyDarwin开源音频解码项目EasyAudioDecoder:基于ffmpeg的安卓音频(AAC、G726)解码库(第一部分,ffmpeg-android的编译)

    ffmpeg是一套开源的,完整的流媒体解决方案.基于它可以很轻松构建一些强大的应用程序.对于流媒体这个行业,ffmpeg就像圣经一样的存在.为了表达敬意,在这里把ffmpeg官网的一段简介搬过来,ff ...

  5. Error:Execution failed for task ':app:clean'. > Unable to delete directory: ***/app/build/generated/***

    第一次从svn拉下来的工程,在clean的时候会出现 Error:Execution failed for task ':app:clean'. > Unable to delete direc ...

  6. ElasticSearch(一)什么是全文检索?

    全文检索 全文检索,即倒排索引.

  7. Node 文件上传,ZIP

    上传文件: 很多人会使用第三包进行文件的上传,例如formidable. 我也研究过,可是与Express3.x框架一起使用时,发现上传的文件总是找不到.结果原因是下面这句导致: app.use(ex ...

  8. PHP开发工作心得

    一.扎实PHP自身的基础知识.函数.常量等,尽量用内置的方法解决这个问题(由于个人写的往往运行效率没有内置方法高): 二.代码尽量少的实现功能(由于PHP的运行事实上是,将咱们的代码先处理成底层语言进 ...

  9. [数据挖掘课程笔记]人工神经网络(ANN)

    人工神经网络(Artificial Neural Networks)顾名思义,是模仿人大脑神经元结构的模型.上图是一个有隐含层的人工神经网络模型.X = (x1,x2,..,xm)是ANN的输入,也就 ...

  10. java之EJB

    EjB,只是一个服务端运行组件,公开接口供客户端以C/S方式调用而已. 最直白,最本质的解释,可参见: http://blog.csdn.net/jojo52013145/article/detail ...