如果要想自己设计一个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. Spring Boot实现STOMP协议的WebSocket

    关注公众号:锅外的大佬 每日推送国外优秀的技术翻译文章,励志帮助国内的开发者更好地成长! WebSocket协议是应用程序处理实时消息的方法之一.最常见的替代方案是长轮询(long polling)和 ...

  2. 深度解析开发项目之 03 - enum的使用

    深度解析开发项目之 03 - enum的使用 01 - 在#import和@interface之间定义typedef enum 注意: 默认是0,1,2,3 02 - 定义可以操作的数据类型的属性 0 ...

  3. Struts2拦截器 解决登录问题

    一.了解Struts2 拦截器[Interceptor] 拦截器的工作原理如图  拦截器是由每一个action请求(request)都包装在一系列的拦截器的内部,通过redirectAction再一次 ...

  4. linux上查看系统内核版本命令(转载)

    uname -a uname -r 查看发行版本信息: 在RedHat系统里,存在一个/etc/redhat-release文件,里面保存了发行版的版本信息 $cat /etc/redhat-rele ...

  5. Mvc之Ajax上传图片

    MyAjaxForm下载地址,点击此处下载 视图部分: @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Lay ...

  6. 如何使Htm页面使用IE9文档模式

    修改Htm页面的方法之一是,在Head->Title下添加<META http-equiv="X-UA-Compatible" content="IE=9&q ...

  7. LNK1112: module machine type 'x64' conflicts with target machine type 'X86'

    1 什么是“module machine type” 这个是当前工程要链接的静态库的target machine type. 2 什么是“target machine type” 这个是当前工程生成的 ...

  8. BZOJ3231: [Sdoi2008]递归数列

    BZOJ3231: [Sdoi2008]递归数列 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + ...

  9. cgic 中文文档

    CGIC英文文档地址:https://boutell.com/cgic/ cgic是用c写cgi程序的一个很小的库,所以英文文档也很少,为了便于日后复习翻看,心血来潮,翻译了一遍. 1. 什么是cgi ...

  10. 对于URL中文和特殊字符的处理方法

    1.中文的处理方法 NSString* string1 = @"https://www.cloudsafe.com/文件夹"; NSString* string2 = [strin ...