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

news/2024/5/19 23:22:57/

文章首发及后续更新: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;应该首先考虑其内置…

干货|手把手教你怎么做好一块PCB!保姆级教程

目录 一.明确设计目标 二.了解所用元器件的功能对布局布线的要求 三. 元器件布局的考虑 四.对布线的考虑 1.传输线 2.传输线的几种类型 3.端接传输线 4.非端接传输线 5.几种端接方式的比较 五.PCB 板的布线技术 一.明确设计目标 接受到一个设计任务,首先要明确其设计目标,是普通…

【vue2】使用elementUI进行表单验证实操(附源码)

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;vue使用elementUI进行表单验证实操&#xff08;附源码&#xff09; 【前言】我们在构建一…

Python无框架分布式爬虫,爬取范例:拼多多商品详情数据,拼多多商品列表数据

拼多多是中国领先的社交电商平台之一&#xff0c;是一家以“团购折扣”为主要运营模式的电商平台。该平台上有海量的商品&#xff0c;对于商家和消费者来说都具有非常大的价值&#xff0c;因此&#xff0c;拼多多商品数据的采集技术非常重要。本文将介绍拼多多商品数据的采集技…

SAM(Segment Anything Model)让CV走到尽头?学CV的研究生还能正常毕业吗?怎么使用SAM?

SAM&#xff08;Segment Anything Model&#xff09;让CV走到尽头&#xff1f;学CV的研究生还能正常毕业吗&#xff1f;怎么使用SAM&#xff1f; 1. 引言 最近无论是在B站、知乎还是论坛、微博&#xff0c;都看了一些有关SAM的讨论。这个号称“CV界ChatGPT”的模型从出生起就…

藏经阁(七)有源蜂鸣器和无源蜂鸣器 解析

文章目录 特征区别场景选型实战应用 特征 有源蜂鸣器特征&#xff1a; 又被称为直流蜂鸣器包含了一个多谐振荡器只要额定直流电压可以在两端发出声音具有驱动控制简单价格略高 无源蜂鸣器特征&#xff1a; 又被称为交流蜂鸣器内部没有振荡器需要在两端施加特定频率的方波电…

mysql-!=,<>,=,<=>,is区别及使用推荐

!和<> 相同点&#xff1a;两个比较符作用相同 不同点&#xff1a;!是ANSI标准中的一部分&#xff0c;因此也可以用在其他数据库中。而<>只能在mysql中使用。 建议&#xff1a;如果可以都用!&#xff0c;这样可以减少必要的迁移成本&#xff0c;如mysql的sql迁移到…

MVC、MVP、MVVM:谁才是Android开发的终极之选?

概述 MVC、MVP、MVVM 都是在 Android 开发中经常用到的架构思想&#xff0c;它们都是为了更好地分离代码、提高代码可复用性、方便维护等目的而设计的。下面对这三种架构思想进行简单的介绍和比较。 MVC MVC 架构是最早被使用的一种架构&#xff0c;它把程序分成了三个部分&…

windows下Tomcat安装

目录 1.安装java环境 2.配置Tomcat环境变量 3.安装服务 4.启动前修改配置文件 &#xff08;1&#xff09;设置tomcat端口 &#xff08;2&#xff09;设置临时日志等文件夹的位置 5.放入应用 6.启动Tomcat服务 1.安装java环境 安装tomcat版本对应的JDK 比如&#xff1a;…

初始单片机.md

1.如何将HEX文件烧录到单片机 STC-ISP STC-ISP是一款单片机下载编程烧录软件&#xff0c;是针对STC系列单片机而设计的&#xff0c;可下载STC89系列、12C2052系列和12C5410等系列的STC单片机&#xff0c;使用简便。 思路&#xff1a;将电脑磁盘上已存在的文件通过串口的方式下…

Linux文件系统 文件恢复

inode和block block 用于存储文件数据。 文件是存储在硬盘上的&#xff0c;硬盘的最小存储单位叫做“扇区”&#xff08;sector&#xff09;&#xff0c;每个扇区存储512字节。连续八个扇区组成一个"块"&#xff08;block&#xff09;&#xff0c;一个块是4K大小&…

Zookeeper实战之客户端Curator vs zkClient

1. zookeeper应用开发 Zookeeper应用开发&#xff0c;需要使用Zookeeper的java 客户端API &#xff0c;去连接和操作Zookeeper 集群。 可以供选择的java 客户端API 有&#xff1a;Zookeeper 官方的 java客户端API&#xff0c;第三方的java客户端API。 Zookeeper官方的客户端…

PAM AppArmor非默认目录构建和安装

在AppArmor零知识学习十二、源码构建&#xff08;9&#xff09;中&#xff0c;详细介绍了PAM AppArmor的构建步骤&#xff0c;但那完全使用的是官网给出的默认参数。如果需要将目标文件生成到指定目录而非默认的/usr&#xff0c;则需要进行一些修改&#xff0c;本文就来详述如何…