如果要想自己设计一个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. 10分钟,解决卖点没创意的难题zz

    创意”,是一个广告人引以为豪又十分头疼的词.有时候,创意来了怎么都挡不住,思如泉涌:有时候,想破脑壳都想不出符合卖点的创意.而笔者告诉我们,有一个方法能轻松解决这个难题. 思路+灵感 问你一个问题:假 ...

  2. Django知识梳理

    请求周期: url > 路由 > 函数或类 > 返回字符串或模板语言 Form 表单提交: 先处理模板语言再讲HTML发出去 提交 > url > 函数或类中的方法  — ...

  3. poj 1703 Find them, Catch them(种类并查集和一种巧妙的方法)

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36176   Accepted: ...

  4. mysql查询sql中检索条件为大批量数据时处理

    当userIdArr数组值为大批量时,应如此优化代码实现

  5. 在VS2015中增加JQuery引用及智能提示

      打开VS2015,从"工具"菜单选择NuGet选项,搜索Jquery,并点击安装.   可以看到解决方案的scripts增加了对应文件的引用   在HTML文件中可以直接引用j ...

  6. oracle 控制文件多路复用

    网上有很多关于控制文件的操作,我大概看了下.有很多都是炒来炒去转来转去.下面以自己理解和操作为例来对oracle的控制文件进行下介绍. 首先介绍下控制文件 在oralce数据库中,控制文件是一个很小的 ...

  7. EasyDarwin开源流媒体服务器gettimeofday性能优化(3000万/秒次优化至8000万次/秒)

    -本文由EasyDarwin开源团队成员贡献 一.问题描述 Easydarwin中大量使用gettimeofday来获取系统时间,对系统性能造成了一定的影响.我们来做个测试: While(1) { G ...

  8. spring 集成 mybatis 后数据源初始化失败问题分析

    问题背景: 项目使用spring,springmvc框架,后边需操作关系数据库,选择了mybatis + durid,集成mybatis后,项目一直启动失败.错误的原因是dataSource初始化的时 ...

  9. 九度OJ 1141:Financial Management (财务管理) (平均数)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:939 解决:489 题目描述: Larry graduated this year and finally has a job. He's ...

  10. Android笔记之文本随滑块移动的SeekBar

    效果图 FloatingTextSeekBar.java package com.bu_ish.blog; import android.content.Context; import android ...