Unity记录3.4-地图-柏林噪声生成 1D 地图及过渡地图

news/2024/11/30 11:36:56/

文章首发及后续更新:https://mwhls.top/4489.html,无图/无目录/格式错误/更多相关请至首发页查看。
新的更新内容请到mwhls.top查看。
欢迎提出任何疑问及批评,非常感谢!

汇总:Unity 记录

摘要:柏林噪声生成 2D 地图,以二维数组表示。

参考:
Unity 中文手册 2021.1
Unity 2D-Extras
Mathf.PerlinNoise

目录
1. 粗糙的 1D 柏林噪声-2023/03/17
2. 陡峭可控的 1D 柏林噪声-2023/03/17
改进思路-2023/03/17
3. 1D 柏林噪声过渡区域-2023/03/17-2023/03/18

1. 粗糙的 1D 柏林噪声-2023/03/17

  • 本来想一步到位,想想算了,脑子不够(拍了拍脑袋,发现空空的)。
  • 实现方式
    • 在取柏林噪声时,y 始终为 0,x 设为当前坐标即可。
  • 效果如下

Unity_011_PerlinNoise1d.png

  • 代码
    int[,] generate_perlin1d(int width, int height, int base_x, int base_y){int[,] offset_array = new int[width, height];float[] perlin_array = new float[width];float perlin_h;for (int i = 0; i < width; i++){perlin_array[i] = Mathf.PerlinNoise(((i + base_x) + 0.5f), 0.5f);}for (int i = 0; i < width; i++){perlin_h = perlin_array[i] * height;for (int j = 0; j < height; j++){if (j < perlin_h){offset_array[i, j] = 1;}}}return offset_array;}

2. 陡峭可控的 1D 柏林噪声-2023/03/17

  • 效果(从左到右,scale分别为 10, 5, 1)

Unity_012_ScaleChange.png

  • 代码
    int[,] generate_perlin1d(int width, int height, int base_x, int base_y, float scale=10f){int[,] map_array = new int[width, height];float perlin_h;for (int i = 0; i < width; i++){perlin_h = height * Mathf.PerlinNoise(((i + base_x)/scale + 0.5f), 0.5f);for (int j = 0; j < height; j++){if (j < perlin_h){map_array[i, j] = 1;}}}return map_array;}

改进思路-2023/03/17

  • 还好没有一步到位,做完之后发现做到这里就ok了。
    • 原本还想弄个噪声变化区域的高度占比,这样可以只在顶部变化,而底部始终填充,但做完发现没必要,直接和其它的叠起来就好。
    • 以及还有想弄陡峭程度的 scale,发现也没必要,越陡,整块面积也要越大,那直接把噪声的生成区域变大就好。
    • 以及多个噪声堆叠,现在想想真是无意义,噪声的叠加还是噪声。
  • 两个缺陷,不同 scale 与 y 时,区域不连续
    • 即当生成区域的 y 值变化,对应的噪声区域也会上下移动。但这可以通过增加一块过渡区,逐渐减少 y 值来解决,如下图
    • Unity_013_yChange.png
    • scale 的变化的话,感觉要计算一下原噪声位置,和新噪声位置,对齐才能实现。
    • 但似乎也能用过渡区域来实现。

3. 1D 柏林噪声过渡区域-2023/03/17-2023/03/18

  • 已知左区块高度及放缩,右区块高度及放缩,两区块间的 y 偏差,实现在两区块间加入过渡区域,让地图衔接平滑。

  • 思路很简单,原来是一大块区域用同一个高度和同一个放缩,现在过渡区域细分,每个x对应一个高度和放缩,以及y偏差,用三个斜率实现就行。

    • 和上面改进思路的图一样,上面只有 y 偏差,现在增加高度变化及放缩变化。
  • 效果:

    • 生成了四个区块,每个区块三个部分,左右两个正常地图,中间一个过渡地图,scale 从 10 5 间过渡,高度从 25 50 间过渡,偏差从 0 50 过渡
    • Unity_014_MapTransition.png
  • 三区块生成代码

        if (input_base.isKeydown("Fire3")){Vector3Int pos_tilemap = tilemap_modify.WorldToCell(input_base.get_mouse_pos(1));int[,] tmp_array = generate_perlin1d(tmp_w, tmp_h, pos_tilemap.x, pos_tilemap.y, scale:noise_scale);ArrayList pos_array = generate_pos_array(pos_tilemap, tmp_array);place_tile(tilemap_modify, pos_array, tile_place);
        pos_tilemap.x += tmp_w;pos_tilemap.y += Mathf.Min(0, tmp_h2);tmp_array = generate_perlin1d_transition(tmp_w2, tmp_h2, tmp_h, noise_scale, tmp_h3, noise_scale2, pos_tilemap.x, pos_tilemap.y);pos_array = generate_pos_array(pos_tilemap, tmp_array);place_tile(tilemap_modify, pos_array, tile_place);pos_tilemap.x += tmp_w2;pos_tilemap.y += Mathf.Max(0, tmp_h2);tmp_array = generate_perlin1d(tmp_w3, tmp_h3, pos_tilemap.x, pos_tilemap.y, scale:noise_scale2);pos_array = generate_pos_array(pos_tilemap, tmp_array);place_tile(tilemap_modify, pos_array, tile_place);</code></pre>
  • 过渡代码
    int[,] generate_perlin1d_transition(int offset_x, int offset_y,int height_left, float scale_left, int height_right, float scale_right,int base_x, int base_y){int height, botton; if (offset_y >= 0){height = Mathf.Max(height_left, height_right + offset_y);botton = 0;} else{height = Mathf.Max(height_left - offset_y, height_right);botton = offset_y;}int[,] map_array = new int[offset_x, height];float perlin_i, height_i, scale_i, offset_y_i;float k_scale = (scale_right - scale_left) / (float)offset_x;float k_height = (height_right - height_left) / (float)offset_x;float k_offset_y = (float)offset_y / (float)offset_x;for (int i = 0; i < offset_x; i++){// alignment height, transit from height_left to height_rightheight_i = height_left + k_height * i;  // perlin heightscale_i = scale_left + k_scale * i;     // perlin scaleoffset_y_i = k_offset_y * i;            // perlin offsetperlin_i = height_i * Mathf.PerlinNoise(((i + base_x)/scale_i + 0.5f), 0.5f);   // perlin yfor (int j = 0; j < height; j++){if (j < perlin_i - botton + offset_y_i){map_array[i, j] = 1;}}
    }return map_array;
}</code></pre>

http://www.ppmy.cn/news/47556.html

相关文章

深入理解栈:从CPU和函数的视角看栈的管理、从栈切换的角度理解进程和协程

我们知道栈被操作系统安排在进程的高地址处&#xff0c;它是向下增长的。但这只是对栈相关知识的“浅尝辄止”。栈是每一个程序员都很熟悉的话题&#xff0c;但你敢说你真的完全了解它吗&#xff1f;我相信&#xff0c;你在工作中肯定遇到过栈溢出&#xff08;StackOverflow&am…

java轻量级框架MiniDao的详解

MiniDao是一款基于Java语言开发的轻量级持久层框架&#xff0c;它的目标是简化数据库操作流程&#xff0c;提高开发效率&#xff0c;减少代码量。MiniDao采用简单的注解配置方式&#xff0c;可以很容易地与Spring等常用框架集成使用。 MiniDao的主要特点包括&#xff1a; 简单…

ChatGPT实战100例 - (03) 网站用不惯?油猴子盘它

文章目录 ChatGPT实战100例 - (03) 网站用不惯&#xff1f;油猴子盘它一、需求与思路二、油猴子脚本二、油猴子脚本部署 ChatGPT实战100例 - (03) 网站用不惯&#xff1f;油猴子盘它 一、需求与思路 需求&#xff1a;网页太长&#xff0c;要回顶部慢慢拖&#xff1f; No&…

盖子的c++小课堂——第十七讲:递归

前言 通知一下&#xff0c;以后每周不定期更新&#xff0c;有可能是周六更新&#xff0c;也可能是周日吧&#xff0c;反正会更新的~~还有我新出的专栏《跟着盖子读论语》&#xff0c;记得订阅一下啊跟着盖子学《论语》_我叫盖子的盖鸭的博客-CSDN博客 三元表达式 三元表达式…

android studio 重装之老年人

原由:前一天估计未正确关机,导致第二天0004蓝屏开机&#xff0c;重装系统&#xff0c;装好androidstudio 以及jdk&#xff0c;adt &#xff08;且adt要新否则连不上&#xff09; a.出现adb device 未知最常见的方案就是先找到占用ADB的端口的程序&#xff0c;然后杀死重启服务…

【Python入门第五十二天】Python丨NumPy 数组过滤

数组过滤 从现有数组中取出一些元素并从中创建新数组称为过滤&#xff08;filtering&#xff09;。 在 NumPy 中&#xff0c;我们使用布尔索引列表来过滤数组。 布尔索引列表是与数组中的索引相对应的布尔值列表。 如果索引处的值为 True&#xff0c;则该元素包含在过滤后的…

分布式定时任务

本文引用了谷粒商城的课程 定时任务 定时任务是我们系统里面经常要用到的一些功能。如每天的支付订单要与支付宝进行对账操作、每个月定期进行财务汇总、在服务空闲时定时统计当天所有信息数据等。 定时任务有个非常流行的框架Quartz和Java原生API的Timer类。Spring框架也可以…

15-Django框架基础(3)

1 Django模板加载与响应 本节我们将重点讲解 Django 的模板语言。 Django 的模板系统将 Python 代码与 HTML 代码解耦&#xff0c;动态地生成 HTML 页面。Django 项目可以配置一个或多个模板引擎&#xff0c;但是通常使用 Django 的模板系统时&#xff0c;应该首先考虑其内置…