程序洞穴生成一(Procedural Cave Generation)
这边博客是我自己学习过程中写的第一篇文章,一方面是想与大家分享好的知识,另一方面是为了监督自己不断的学习,希望能给大家带来好的内容分享。
这篇文章的内容是搬运自Youtube上的Sebastian大佬的视频,这个Up主有很多的Unity、Shader、数学、算法等的视频教学,内容都很不错而且讲解非常的清楚,英语不错的小伙伴可以去Youtube上去学习,视频第一课的链接https://www.youtube.com/watch?v=v7yyZZjF1z4&list=PLFt_AvWsXl0eZgMK_DT5_biRkWXftAOf9。不太想看英文教程的下面我用文字的方式来分享。
首先定义出所需要的变量
public int width; //地图的宽度public int height; //地图的高度public string seed; //随机种子public bool useRandomSeed; //是否使用随机中的Flag[Range(0, 100)]public int randomFillPercent; //填充百分比int[,] map; //地图的信息
变量的意义我也都写在上面了。
首先我们要做的就是生成随机的单个Cube通过不同颜色来表现的地图效果。然后我们定义一个GenerateMap的函数用来生成地图信息。初始化二维数组map。第一步生成纯随机无规律的地图信息,通过系统的Random函数来为map数组生成随机的0或者1这里1代表Wall(墙)。设置好宽度高度和填充百分比,此时生成的地图信息是随机,无规律的,如果1用黑色的块,0用白色的块来生成出来地图将会是这样的。
我这里width=128,height=72,RandomFillPercent = 45
这样的地图当然是没法用的,所以我们要给地图信息上规则,平滑地图信息。编写一个SmoothMap函数。平滑地图的原理是这样的,两层循环遍历二维数组map,然后判断一个地图信息点的周围的墙的数量,然后设定一个阈值,墙的数量大于这个阈值就将这个位置的地图信息设置为1(墙),如果小于这个阈值,那么就将地图设置为0(空),然后循环多次下来地图的效果就慢慢呈现出来了,视频作者循环的次数是5次,然后阈值是4,实现出来的效果如下图所示。
现在生成的地图是不是就有点像模像样了呢。
最后再讲一个如果生成显示在Scene视图中,直接贴代码,比较简单很好理解
/// <summary>/// 绘制/// </summary>private void OnDrawGizmos(){if (map != null){for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){Gizmos.color = (map[x, y] == 1) ? Color.black : Color.white;Vector3 pos = new Vector3(-width / 2 + x + .5f, 0, -height / 2 + y + .5f);Gizmos.DrawCube(pos, Vector3.one);}}}}
运行,然后调节Scene视图的视角是从上往下,然后设置成正交视角就能看到效果啦,视频作者还编写了一个鼠标点击就更换地图的随机生成,当然想随机生成还需要设置系统的随机种子。随机种子的生成是获取运行时间的字符串,然后拿到字符串的哈希码作为随机种子传进去,这样每次生成的地图就可以保证不重复了。
完整代码:
public int width; //地图的宽度public int height; //地图的高度public string seed; //随机种子public bool useRandomSeed; //是否使用随机中的Flag[Range(0, 100)]public int randomFillPercent; //填充百分比int[,] map; //地图的信息private void Start(){GenerateMap(); }private void Update(){//测试点击鼠标生成新的地图if (Input.GetMouseButtonDown(0)){GenerateMap();}}/// <summary>/// 生成地图/// </summary>void GenerateMap(){map = new int[width, height];RandomFillMap();for (int i = 0; i < 5; i++){SmoothMap();}}/// <summary>/// 随机填充地图/// </summary>void RandomFillMap(){if (useRandomSeed){seed = Time.time.ToString();}System.Random pseudoRandom = new System.Random(seed.GetHashCode());for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){//将周围包括起来if (x == 0 || x == width - 1 || y == 0 || y == height - 1){map[x, y] = 1;}else{map[x, y] = (pseudoRandom.Next(0, 100) < randomFillPercent) ? 1 : 0;}}}}/// <summary>/// 让地图变得平滑/// </summary>void SmoothMap(){for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){int neighbourWallTiles = GetSurroundingWallCount(x, y);///这里的数字4和不等式的等于号是否要加,自己可以尝试,然后看运行的效果。if (neighbourWallTiles > 4){map[x, y] = 1;}else if (neighbourWallTiles < 4){map[x, y] = 0;}}}}/// <summary>/// 获取周围的墙的数量,(这里的墙指的就是Map【x,y】 = 0)/// </summary>/// <param name="gridX">坐标x</param>/// <param name="gridY">坐标y</param>/// <returns></returns>int GetSurroundingWallCount(int gridX, int gridY){int wallCount = 0;for (int neighbourX = gridX - 1; neighbourX <= gridX + 1; neighbourX++){for (int neighbourY = gridY - 1; neighbourY <= gridY + 1; neighbourY++){if (neighbourX >= 0 && neighbourX < width && neighbourY >= 0 && neighbourY < height){if (neighbourX != gridX || neighbourY != gridY){wallCount += map[neighbourX, neighbourY];}}else{wallCount++;}}}return wallCount;}/// <summary>/// 绘制/// </summary>private void OnDrawGizmos(){if (map != null){for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){Gizmos.color = (map[x, y] == 1) ? Color.black : Color.white;Vector3 pos = new Vector3(-width / 2 + x + .5f, 0, -height / 2 + y + .5f);Gizmos.DrawCube(pos, Vector3.one);}}}}
第一部分不多也比较好理解,就先讲到这里了,想往后学习的可以去上面的视频链接找到视频作者。
程序洞穴生成一(Procedural Cave Generation)相关推荐
- 程序洞穴生成六(Procedural Cave Generation)
这次直接将后面的内容一次性讲完啦.其实本来是想一个一个视频的讲的,但是今天才发现我上次准备好的内容没有写然后没有发,所以今天就一起讲了,其实剩下的视频是有三个的,最后一个视频主要是作者的应用,写了一些 ...
- 程序洞穴生成三(Procedural Cave Generation)
上一篇文章我们已经将地图的信息转换成了模型需要的Meh信息,但是生成的是一个平面的效果,所以接下来就要通过其他的方法生成3D的墙面,将上一篇生成的地图的边界衍生出垂直的墙面. 本篇本章的内容的视频链接 ...
- GPU Pro2 - 3.Procedural Content Generation on the GPU
GPU Pro2 - 3.Procedural Content Generation on the GPU 这篇文章着重介绍了基于Brownian 噪声和高度图在GPU中实时生成和渲染无限大地形系统 ...
- Procedural Landmass Generation开源库测评
[博物纳新]是UWA旨在为开发者推荐新颖.易用.有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目.前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性.很多时候,我们并不知道自己 ...
- ASP程序快速生成Excel文件
ASP程序快速生成Excel文件 在一个web项目中,要求将数据生成Excel文件保存到本地,最早使用的方法是直接使用Microsoft的Office Web组件,但是总体感觉是慢(微软的通病).然后 ...
- Java黑皮书课后题第7章:*7.7(统计个位数的数目)编写一个程序,生成0和9之间的100个随机整数,然后显示每一个数出现的次数
*7.7(统计个位数的数目)编写一个程序,生成0和9之间的100个随机整数,然后显示每一个数出现的次数 题目 题目描述 破题 代码 运行示例 题目 题目描述 *7.7(统计个位数的数目)编写一个程序, ...
- 额,你在main.xml中加了一个id以后,要右键点save,才会将这个id加入到R中,否则是没有的。。。R里的东西是程序自动生成的~~~...
我修改了 main.xml 然后我在主函数中调用main里面的东西 例如在main.xml加了一个id 我在主函数用 R.id老是调用不出来 如何才能快速的准确的调用出 main.xml里面的东西呢? ...
- php小程序码生成并保存,小程序中如何生成小程序码
导语: 小程序是一种不需要下载安装即可使用的应用,它实现了应用"触手可及"的梦想,用户扫一扫或者搜一下即可打开应用.也体现了"用完即走"的理念,用户不用关心是否 ...
- poi生成word不可以修改_操作不懂技术就可以做小程序无限生成平台的创业项目实操教程...
小程序现在是个风口,很多人都涉足这个行业,不过大部分都是站在用户的角度去接触的小程序,作为创业者,我们有没有机会可以给别人做小程序呢?当然是可以的,今天我们就来操作这样一个小程序无限生成的项目,对于零 ...
最新文章
- Java开发面试问题,牛逼轰轰!
- POJ3189二分最大流(枚举下界,二分宽度,最大流判断可行性)
- 3 MIGO采购订单收货报错-表T169P,表目S001不存在
- 为对抗训练的理论工作添砖加瓦:选择核心子集进行训练,大大缩短训练时间...
- PAT1103 Integer Factorization (30)(DFS:回溯)
- C++程序设计【一】之 C++ 语言简介
- Kramdown 配置不当引发 GitHub Pages 多个 RCE,得 $2.5万($6.1万系列之二)
- 使用 ADO 向数据库中存储一张图片
- PyTorch并行与分布式(四)Distributed Data Papallel
- java服务器必读_Java服务器端编程安全必读
- 未能找到任何适合于指定的区域性或非特定区域性的资源。请确保在编译时已将“***Form.resources”正确嵌入或链接到程序集“***”。。。
- 一棵树的生物量怎么算_2019玩花园 | 夏天怎么办?
- 闲置手机制作电脑副屏-状态监控(含软件)
- xodo pdf android,手机上最好用的pdf阅读器,没有之一——【Xodo】
- 2018届android校招面试总结:百度,大疆,乐视,知乎
- 什么是幂等?如何实现
- 车牌识别系列(二)生成具有真实感的(realistic)车牌数据
- pycharm发送邮件(QQ邮箱和网易163为例)
- 帝国cms模板html文件夹,帝国CMS模板建站e文件夹各个文件功能说明
- 京东一键自动领取京豆、全自动签到、农场浇水、超市兑奖
热门文章
- 【无标题】AttributeError: ‘TransposedFont‘ object has no attribute ‘getbbox‘
- PS2019替换照片背景
- 设置计算机光驱启动不了怎么办,联想台式电脑设置bios时U盘、光盘都启动不了是怎么回事?...
- Java中的poi是什么_java中的POI
- 使用开源调研工具Prophet是一种什么体验?
- 人大徐海照健康中原 国稻种芯-万祥军:河南农业大健康产业
- 时间序列分析——知乎话题讨论(收集)
- 一个计算机系统可以用吗,如果把系统放在U盘里,真的可以在任何一台电脑上使用吗?...
- Redis数据结构实战演练,看看微博、微信、购物车、抽奖小程序是如何使用的?
- Nacos单机版配置mysql数据库