【Godot4.3】2D程序生成植物概论

概述

Godot的2D程序化植物生成是我一直想要探讨的一个内容,但是一直没有真正开动,在刚过去的中秋节假期期间,在老家无聊,在一个素描本上构思了一系列想法。本篇就基于这些自己的想法介绍一下程序化植物生成的基本思路。不一定对,不一定能实现到什么程度,但是思考、探索和总结的过程,本身可能比结果更重要。

程序所要生成的植物种类

最常见的植物包括树、花和草三种。其下又可以分为各种具体类型。

植物程序生成,就是利用参数化形式创建并绘制植物。最常见且基础的手段是分形递归。

要想很专业的生成各类植物,需要学习一点专业的《植物学》。理解包括花序类型等知识,而不是凭空捏造和想象。

Godot中的2D植物程序化生成方案

  • DrawFunctionBased:也就是基于绘图函数,以及纯几何图形的
  • TextureBased:依赖于Texture2D的,整体和局部采用图片按一定算法排列
  • StatusBased:基于图片或图片序列的多状态切换(参照基于状态的游戏元素一文)

根据方案的不同,设计思路和算法不同。

DrawFunctionBased

基于分形和递归思路+CanvasItem的绘图函数,可以很容易的创建和绘制分形植物。

这里又有两种思路:

  • 一种是完全基于算法生成,按顺序叠加绘制完成。
  • 另一种是基于曲线和节点的控制:也就是在递归算法基础上施加手动影响

分形树

这个例子是我比较迷恋分形的那段时间的一个例子:

extends Node2Dvar linesfunc _ready() -> void:lines = tree(Vector2(200,200),100)func _draw() -> void:draw_multiline(lines,Color.AQUAMARINE,1)pass# 返回树形曲线的线段 - 可以使用draw_multiline绘制和显示
func tree(start_pos:Vector2,length:float,max_fork:int =5,steps:int =5):var lines:PackedVector2Array = []if steps > 0:for i in randi_range(2,max_fork):var deg = randf_range(deg_to_rad(-60),deg_to_rad(60))var end_pos = start_pos+ Vector2.UP.rotated(deg) * lengthlines.append_array([start_pos,end_pos])lines.append_array(tree(end_pos,length/2,5,steps-1))return lines

在这里插入图片描述

其实关于分形树,网上有太多人用各种绘图语言和工具实现过,甚至很多特别好看。

我这里举分形树的例子,只是想说,分形和递归思路在植物生成方面的确是基础思想。

TextureBased

将植物分成多个有机组成部分,比如把树分为枝干、树叶、花和果实,每个部分指定一张图片。

然后用算法生成和绘制。

簇排列器

花或叶是按一定的秩序排列的,可以抽象出几种:用于花或叶的绘制。

排列器

  • 线状:根据直线或曲线路径层叠排列
  • 鱼刺状:两侧成角度排列。
  • 同心环形阵列
  • 多层扇形层叠

在这里插入图片描述


时间比较紧,没来及画示意图,先直接上了自己手绘的草图。 – 2024年9月22日14:43:38


植物分层

无论是树、花还是草,都是占有一定空间体积的,也就是有纵深,而不是二维的平面。

表示纵深最好的方法就是分层+颜色的深浅。

以树为例:

  • 在枝干层的前后可以加若高层叶簇
  • 每个叶簇又可以是若干层树叶,中间可以夹杂花或者果实

这样,树就立体了起来。

在这里插入图片描述

StatusBased

分析所需要植物的各种状态,然后绘制和分配相应的图片或图片序列。

游戏中根据需要切换状态并绘制就可以了。

在这里插入图片描述

植物分布器

在搞定基础植物的基础上,植物的分布也有的搞。

  • 通过编写分布器,可以程序化的组合和分布各类植物。
  • 可以按曲线、多边形区域等进行分布。
  • 分布过程可以给予一定的位移抖动、随机缩放。而且设定多种植物的出现权重。

总结

初步设想,但可行性比较高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/429713.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux:login shell和non-login shell以及其配置文件

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 shell是Linux与外界交互的程序,登录shell有两种方式,login shell与non-login shell,它们的区别是读取的配置文件不同,本…

Spring6梳理10—— 依赖注入之注入数组类型属性

以上笔记来源: 尚硅谷Spring零基础入门到进阶,一套搞定spring6全套视频教程(源码级讲解)https://www.bilibili.com/video/BV1kR4y1b7Qc 目录 10 依赖注入之注入数组类型属性 10.1 创建Emp实体类,Dept实体类 10.2…

Linux学习笔记(2)

Linux学习笔记(2) 知识点: 1.打包、压缩——是什么、为什么、怎么做? 什么是打包、压缩? 打包:把文件合并。 压缩:通过一定算法减少体积。 为什么要进行打包、压缩? 打包&…

数据结构之堆(优先级队列)

“愿独立的你,在随心而行的途中,学会释怀而止,而非一时放纵之后而任性非为” 这好像是我第一次写关于数据结构的文章吧,关于数据结构,那真的是太奥秘了,想领略其中的奥秘,必须得付出相应的努力…

C++:类和对象OJ题

目录 一、求123...n 二、计算日期到天数的转换 三、日期差值 四、打印日期 一、求123...n 这里先把题目链接放在这里求123.....n 描述: 求123...n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C…

UnLua实现继承

一、在蓝图中实现继承 1、创建父类,并绑定Lua脚本 2、创建子类蓝图,如果先创建的子类,可以修改父类继承 注意,提示选择继承父类的接口! 二、在Lua中实现继承 1、在父类Lua脚本中实现函数 BP_CharacterBase.lua func…

一劳永逸:用脚本实现夸克网盘内容自动更新

系统环境:debian/ubuntu 、 安装了python3 原作者项目:https://github.com/Cp0204/quark-auto-save 感谢 缘起 我喜欢看电影追剧,会经常转存一些资源到夸克网盘,电影还好,如果是电视剧,麻烦就来了。 对于一…

【STL】 set 与 multiset:基础、操作与应用

在 C 标准库中&#xff0c;set 和 multiset 是两个非常常见的关联容器&#xff0c;主要用于存储和管理具有一定规则的数据集合。本文将详细讲解如何使用这两个容器&#xff0c;并结合实例代码&#xff0c;分析其操作和特性。 0.基础操作概览 0.1.构造&#xff1a; set<T&…

深度学习:神经网络--手写数字识别

目录 一、datasets 1.datasets简介 2.主要特点 二、MNIST 三、使用神经网络实现手写数字识别 1.创建数据加载器 2.判断是否使用GPU 3.创建神经网络 4.创建训练集模型 5.创建测试集模型 6.创建损失函数和优化器并训练 一、datasets 1.datasets简介 datasets是一个广…

[mysql]mysql排序和分页

#排序和分页本身是两块内容,因为都比较简单,我们就把它分到通一个内容里. #1排序: SELECT * FROM employees #我们会发现,我们没有做排序操作,但是最后出来的107条结果还是会按顺序发出,而且是每次都一样.这我们就有一个疑惑了,现在我们的数据库是根据什么来排序的,在我们没有进…

windows 驱动实例分析系列-COM驱动案例讲解

COM也被称之为串口,这是一种非常简单的通讯接口,这种结构简单的接口被广泛的应用在开发中,几乎所有系统都能支持这种通讯接口,它有RS232和RS485等分支,但一般我们都会使用RS232作为常见的串口,因为它足够简单和高效。 几乎所有的开发板,都会提供用于烧录、调试、日志的…

redis为什么不使用一致性hash

Redis节点间通信时&#xff0c;心跳包会携带节点的所有槽信息&#xff0c;它能以幂等方式来更新配置。如果采用 16384 个插槽&#xff0c;占空间 2KB (16384/8);如果采用 65536 个插槽&#xff0c;占空间 8KB (65536/8)。 今天我们聊个知识点为什么Redis使用哈希槽而不是一致性…

FastAPI 的隐藏宝石:自动生成 TypeScript 客户端

在现代 Web 开发中&#xff0c;前后端分离已成为标准做法。这种架构允许前端和后端独立开发和扩展&#xff0c;但同时也带来了如何高效交互的问题。FastAPI&#xff0c;作为一个新兴的 Python Web 框架&#xff0c;提供了一个优雅的解决方案&#xff1a;自动生成客户端代码。本…

引领长期投资新篇章:价值增长与财务安全的双重保障

随着全球金融市场的不断演变&#xff0c;长期投资策略因其稳健性和对价值增长的显著推动作用而日益受到投资者的重视。在这一背景下&#xff0c;Zeal Digital Shares&#xff08;ZDS&#xff09;项目以其创新的数字股票产品&#xff0c;为全球投资者提供了一个全新的长期投资平…

re题(38)BUUCTF-[FlareOn6]Overlong

BUUCTF在线评测 (buuoj.cn) 运行一下.exe文件 查壳是32位的文件&#xff0c;放到ida反汇编 对unk_402008前28位进行一个操作&#xff0c;我们看到运行.exe文件的窗口正好是28个字符&#xff0c;而unk_402008中不止28个数据&#xff0c;所以猜测MessageBoxA&#xff08;&#x…

cv中每个patch的关联

在计算机视觉任务中&#xff0c;当图像被划分为多个小块&#xff08;patches&#xff09;时&#xff0c;每个 patch 的关联性可以通过不同的方法来计算。具体取决于使用的模型和任务&#xff0c;以下是一些常见的计算 patch 关联性的方法&#xff1a; 1. Vision Transformer (…

Shell运行原理与Linux权限概念

shell的运行原理 Linux严格意义上说的是一个操作系统。我们称之为“核心&#xff08;kernel&#xff09;”&#xff0c;但我们一般用户&#xff0c;不能直接使用kernel&#xff0c;二十通过kernel的“外壳”程序&#xff0c;也就是所谓的shell&#xff0c;来与kernel沟通。 从…

网络穿透:TCP 打洞、UDP 打洞与 UPnP

在现代网络中&#xff0c;很多设备都处于 NAT&#xff08;网络地址转换&#xff09;或防火墙后面&#xff0c;这使得直接访问这些设备变得困难。在这种情况下&#xff0c;网络穿透技术就显得非常重要。本文将介绍三种常用的网络穿透技术&#xff1a;TCP 打洞、UDP 打洞和 UPnP。…

qt-C++笔记之作用等同的宏和关键字

qt-C笔记之作用等同的宏和关键字 code review! Q_SLOT 和 slots&#xff1a; Q_SLOT是slots的替代宏&#xff0c;用于声明槽函数。 Q_SIGNAL 和 signals&#xff1a; Q_SIGNAL类似于signals&#xff0c;用于声明信号。 Q_EMIT 和 emit&#xff1a; Q_EMIT 是 Qt 中用于发射…

18.2K Star,AI 高效视频监控摄像头

Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 导语 在家庭和企业安防领域&#xff0c;实时视频监控是保障安全的核…