【Godot4.2】GDScript数组分类及类型化数组和紧缩数组概述

概述

GDScript的数组是一种很常用的数据类型。本文主要阐述一下GDScript数组分类,以及官方文档和大多数视频或教程较少提及的类型化数组和紧缩数组。

GDScript数组分类

通过反复查阅GDScript内置文档并进行细节比较,发现GDScript的数组,可以划分为三类

  • 普通数组Array,不限定元素的类型,同一个数组可以存储不同类型的数据元素。
  • 类型化数组Array[type],在Array的基础上限定只能存储一种类型的数据元素。
  • 紧缩数组Packed*Array,数据紧密存放,在数组比较大时可以节省内存。包括:PackedInt32ArrayPackedInt64ArrayPackedFloat32ArrayPackedFloat64ArrayPackedStringArrayPackedVector2ArrayPackedVector3ArrayPackedColorArrayPackedByteArray。其中PackedByteArray代表二进制的字节数组,与其他紧缩数组在代表的意义和所提供的方法方面是完全不同的。

关于数组分类总结如下表:

分组中文名称类型(typeof)备注
普通数组Array普通数组TYPE_ARRAY元素类型可不一致
类型化数组Array[type]类型化数组TYPE_ARRAY元素类型必须一致
紧缩数组PackedByteArray字节紧缩数组TYPE_PACKED_BYTE_ARRAY音频、图片等可能会以此形式存储
PackedInt32Array32位整数紧缩数组TYPE_PACKED_INT32_ARRAY紧缩数组中比较特殊的一位
PackedInt64Array64位整数紧缩数组TYPE_PACKED_INT64_ARRAY方法完全一样,但参数不一样
PackedFloat32Array32位浮点数紧缩数组TYPE_PACKED_FLOAT32_ARRAY
PackedFloat64Array64位浮点数紧缩数组TYPE_PACKED_FLOAT64_ARRAY
PackedStringArray字符串紧缩数组TYPE_PACKED_STRING_ARRAY
PackedVector2ArrayVector2紧缩数组TYPE_PACKED_VECTOR2_ARRAY
PackedVector3ArrayVector3紧缩数组TYPE_PACKED_VECTOR3_ARRAY
PackedColorArrayColor紧缩数组TYPE_PACKED_COLOR_ARRAY

普通数组

GDScript普通数组的使用方法,请查阅:
【Godot4.2】普通数组Array使用全解析 一文。

类型化数组

  • 类型化数组是在普通数组之上添加了一层限定,即限定了所存储的元素类型
  • 形式为Array[type],其中type可以是基础数据类型或者Object及其子类型(包括各种NodeResource等)。

申明与创建

可以用如下形式创建类型化数组:

var arr1:Array[int]          # 申明一个元素都是int类型的数组
var arr2:Array[String]       # 申明一个元素都是String类型的数组
var arr3:Array[Button]       # 申明一个元素都是Button控件的数组
var arr4:Array[PackedScene]  # 申明一个元素都是PackedScene的数组

可以看到,只需要对申明的数组变量用Array[type]形式显式申明其类型即可。
其他的操作与普通Array没有区别。

同时Array提供了一个构造函数,可以用构造函数形式创建类型化数组。其形式如下:

Array(base:Array,type:int,class_name:StringName,script:Variant)

其中:

  • base:是要被类型化的Array数组,可以传入一个空数组。
  • type:指定元素的类型,基础数据类型intfloatString等,以及内置或自定义的NodeResource
  • class_name:是具体的类名,比如ButtonPackedScene等。
  • script:自定义节点类型或资源类型的脚本?(尚有疑问,谨待确认)

比如,申明一个PackedScene类型作为元素的类型化数组,我们可以用常用形式:

var arr:Array[PackedScene]     # 形式1

也可以用构造函数形式:

var arr = Array([],TYPE_OBJECT,"PackedScene",null)   # 形式2

两者申明的类型化数组没有本质上的区别,只是后者提供了一种字符串参数形式创建的类型化数组的方法,在某些场景下可能用得到。

数组的类型化判断以及元素类型信息获取

Array类型提供了几个方法用于判断数组是否是类型化数组,以及获取元素类信息等。

  • is_typed():判断一个数组是否是类型化的。
    注意Packed*Array不算在Array或者类型化数组范畴,也就没有is_typed()等方法,所以不能用is_typed()判断其是否类型化。
var arr1:Array[PackedScene]
var arr2 = []

print(arr1.is_typed()) # true
print(arr2.is_typed()) # flase
  • is_same_typed():判断两个类型化数组的类型是否相同。
var arr1:Array[PackedScene]
var arr2:Array[PackedScene]
var arr3:Array[int]

print(arr1.is_same_typed(arr2)) # true
print(arr1.is_same_typed(arr3)) # flase
  • get_typed_builtin():返回类型化的数组的内置类型(Variant.Type),如果是内置数据类型,返回相应的类型常量,如果是节点或资源类型,统一返回TYPE_OBJECT (数值24)
var arr1:Array[int]
var arr2:Array[Button]
var arr3:Array[PackedScene]

print(arr1.get_typed_builtin()) # 2 = TYPE_INT
print(arr2.get_typed_builtin()) # 24 = TYPE_OBJECT
print(arr3.get_typed_builtin()) # 24 = TYPE_OBJECT
  • get_typed_class_name()返回类型化数组具体的元素类型名称,基础数据类型返回空字符串,节点或资源类型返回具体类名。
var arr1:Array[int]
var arr2:Array[Button]
var arr3:Array[PackedScene]

print(arr1.get_typed_class_name()) # ""
print(arr2.get_typed_class_name()) # "Button"
print(arr3.get_typed_class_name()) # "PackedScene"
  • get_typed_script():如果是自定义节点或资源类型,可以返回其脚本对象,内置数据类型或内置节点、资源类型,则返回<Object#null>
var arr:Array[PackedScene]
print(arr.get_typed_builtin())     # 24 = TYPE_OBJECT
print(arr.get_typed_class_name())  # "PackedScene"
print(arr.get_typed_script())      # <Object#null>

紧缩数组

Packed*Array形式的数组类型被称为“紧缩数组”类型。包括:

中文名称类型(typeof)
PackedByteArray字节紧缩数组TYPE_PACKED_BYTE_ARRAY
PackedInt32Array32位整数紧缩数组TYPE_PACKED_INT32_ARRAY
PackedInt64Array64位整数紧缩数组TYPE_PACKED_INT64_ARRAY
PackedFloat32Array32位浮点数紧缩数组TYPE_PACKED_FLOAT32_ARRAY
PackedFloat64Array64位浮点数紧缩数组TYPE_PACKED_FLOAT64_ARRAY
PackedStringArray字符串紧缩数组TYPE_PACKED_STRING_ARRAY
PackedVector2ArrayVector2紧缩数组TYPE_PACKED_VECTOR2_ARRAY
PackedVector3ArrayVector3紧缩数组TYPE_PACKED_VECTOR3_ARRAY
PackedColorArrayColor紧缩数组TYPE_PACKED_COLOR_ARRAY

紧缩数组类型与普通数组、类型化数组的关系

  • ArrayPacked*Array在内存中都是连续存放的,但是前者存放的是Variant类型, Variant类型固定占20字节,并且可以在其中存储几乎任何引擎数据类型。
  • 类型化数组是限定Array只能存储一种类型的数据元素,也就是将Variant限定为了具体的数据类型(比如说int),但其Array的本质和用Variant类型存储数据元素的本质没有变化。
  • 而具体的Packed*Array,则使用相应的具体类型,而不是Variant类型存储元素数据,所以相比类型化数组更加紧凑,所以相对普通Array和类型化数组Array[type]被称为紧缩数组

在这里插入图片描述

字节紧缩数组(PackedByteArray)

字节紧缩数组PackedByteArray算是比较特殊的一种紧缩数组,它的API和其他几种紧缩数组的不同,用途也不同

数组和紧缩数组间的转化关系

  • 普通数组Array(包括类型化数组Array[type])可以通过Packed*Array(Array)形式也就是相应的紧缩数组的构造函数形式转化为紧缩数组,其过程会对元素类型进行强制转换;
var arr1:Array = [1,"张三",Button.new()]
var pk_arr1 = PackedInt32Array(arr1)
var pk_arr2 = PackedFloat32Array(arr1)
var pk_arr3 = PackedStringArray(arr1)
var pk_arr4 = PackedByteArray(arr1)

print(arr1)    # [1, "张三", <Button#7394641913158>]
print(pk_arr1) # [1, 0, 0]
print(pk_arr2) # [1, 0, 0]
print(pk_arr3) # ["1", "张三", "<Button#6977593879327>"]
print(pk_arr4) # [1, 0, 0]
var arr1:Array[Button] = [Button.new(),Button.new()]
var pk_arr1 = PackedInt32Array(arr1)
var pk_arr2 = PackedFloat32Array(arr1)
var pk_arr3 = PackedStringArray(arr1)
var pk_arr4 = PackedByteArray(arr1)

print(arr1)    # [<Button#8468215966358>, <Button#8468266298058>]
print(pk_arr1) # [0, 0]
print(pk_arr2) # [0, 0]
print(pk_arr3) # ["<Button#8468215966358>", "<Button#8468266298058>"]
print(pk_arr4) # [0, 0]
  • Packed*Array(Array)可以通过to_byte_array()方法转换为PackedByteArray
var arr1:PackedInt32Array = [1,2,4,5,6,7,8]
var bt_arr1 = arr1.to_byte_array()

print(bt_arr1 is PackedByteArray) # true
  • PackedByteArray则可以使用to_float32_array()to_float64_array()to_int32_array()to_int64_array()转化为PackedFloat32Array PackedFloat64Array PackedInt32Array PackedInt64Array

普通数组转字节紧缩数组

var arr = ["张三","李四","王五"]
	
print(PackedByteArray(arr)) # [0, 0, 0]
var arr:PackedStringArray = ["张三","李四","王五"]
	
print(arr.to_byte_array()) # [208, 234, 206, 112, 47, 1, 0, 0, 192, 232, 206, 112, 47, 1, 0, 0, 128, 233, 206, 112, 47, 1, 0, 0]

可以看到普通的字符串数组用PackedByteArray()构造函数直接转换是无效的。
而是应该将数组显示申明为PackedStringArray类型,再调用to_byte_array()方法转换为PackedByteArray

var arr = [1,2,3]
	
print(PackedByteArray(arr)) # [1,2,3]
var arr = [1.5,23.45,36]
	
print(PackedByteArray(arr)) # [1, 23, 36]

普通的纯数字数组通过PackedByteArray()构造函数直接转换有效,但浮点数会被自动转化为整数(向下取整)。


提示
直接用print()方式打印PackedByteArray其每个字节都显示为10进制数字,有时候不是太利于理解。
在《对数组的函数扩充》一文中,编写了相应的函数可以将10进制显示为2进制。下文中显示的二进制形式就是基于相应函数而来。


整形、浮点型紧缩数组转PackedByteArray

var arr1:PackedInt32Array = [1]
var arr2:PackedInt64Array = [1]
var arr3:PackedFloat32Array = [1.5]
var arr4:PackedFloat64Array = [1.5]

print(arr1.to_byte_array()) # [1, 0, 0, 0]
# [00000001,00000000,00000000,00000000]

print(arr2.to_byte_array()) # [1, 0, 0, 0, 0, 0, 0, 0]
# [00000001,00000000,00000000,00000000,00000000,00000000,00000000,00000000]

print(arr3.to_byte_array()) # [0, 0, 192, 63]
# [00000000,00000000,11000000,00111111]

print(arr4.to_byte_array()) # [0, 0, 0, 0, 0, 0, 248, 63]
# [00000000,00000000,00000000,00000000,00000000,00000000,11000000,00111111]

可以看到:

  • Int32Float32占4字节,Int64Float64占8字节。
  • 因此PackedInt32ArrayPackedFloat32Array的一个元素转为PackedByteArray的4个元素,分别对应4个字节
  • 反过来PackedByteArrayPackedInt32ArrayPackedFloat32Array时,是将4个元素转化为1个整数

下图表示一个包含2个元素的PackedInt32Array,在内存中的实际表示。而其每个字节组成的数组就可以看为其PackedByteArray形式。

PackedStringArray转PackedByteArray

var arr1:PackedStringArray = ["a"]
var arr2:PackedStringArray = ["啊"]
var arr3:PackedStringArray = ["a","b","c"]
var arr4:PackedStringArray = ["啊","你好","张三"]

print(arr1.to_byte_array()) # [16, 34, 29, 73, 196, 2, 0, 0]

print(arr2.to_byte_array()) # [80, 27, 29, 73, 196, 2, 0, 0]

print(arr3.to_byte_array()) 
# [16, 34, 29, 73, 196, 2, 0, 0, 144, 90, 29, 73, 196, 2, 0, 0, 208, 35, 29, 73, 196, 2, 0, 0]

print(arr4.to_byte_array()) 
# [80, 27, 29, 73, 196, 2, 0, 0, 128, 119, 41, 72, 196, 2, 0, 0, 0, 121, 41, 72, 196, 2, 0, 0]
print("a".to_ascii_buffer())   # [97]
print("a".to_utf8_buffer())	   # [97]
print("a".to_utf16_buffer())   # [97, 0]
print("a".to_utf32_buffer())   # [97, 0, 0, 0]
print("a".to_wchar_buffer())   # [97, 0]
var string = "张三"
var byte = string.to_utf8_buffer()
print(byte)	              # [229, 188, 160, 228, 184, 137]
print(slices_arr(byte,3)) # [[229, 188, 160], [228, 184, 137]]
print(show_byte_array_string(byte,3))
# ["11100101", "10111100", "10100000"],
# ["11100100", "10111000", "10001001"]

可以看到PackedStringArray转为PackedByteArray后,存储的并不是字符串本身的二进制编码形式,而是指向字符转在内存中的地址(地址占8个字节)。

PackedColorArray --> PackedByteArray

Color以RGBA形式构造,每一个分量为一个Float32,则在PackedByteArray中一个颜色是由四组四个字节的形式表示。

var arr:PackedColorArray = [Color.YELLOW]
var byte = arr.to_byte_array()

print(byte)	# [0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 128, 63]

print(slices_arr(byte,4)) 
# [[0, 0, 128, 63], [0, 0, 128, 63], [0, 0, 0, 0], [0, 0, 128, 63]]
# [r,g,b,a]

print(show_byte_array_string(byte,4))
# ["00000000", "00000000", "10000000", "00111111"],    # R
# ["00000000", "00000000", "10000000", "00111111"],    # G
# ["00000000", "00000000", "00000000", "00000000"],    # B
# ["00000000", "00000000", "10000000", "00111111"]     # A

PackedVector2Array/PackedVector3Array --> PackedByteArray

var arr:PackedVector2Array = [Vector2(100,100)]
	
var byte = arr.to_byte_array()
print(byte)	              # [0, 0, 200, 66, 0, 0, 200, 66]
print(slices_arr(byte,4)) # [[0, 0, 200, 66], [0, 0, 200, 66]]

print(show_byte_array_string(byte,4))
# ["00000000", "00000000", "11001000", "01000010"],   # X
# ["00000000", "00000000", "11001000", "01000010"]    # Y
var arr:PackedVector3Array = [Vector3(100,100,100)]
	
var byte = arr.to_byte_array()
print(byte)	              # [0, 0, 200, 66, 0, 0, 200, 66, 0, 0, 200, 66]
print(slices_arr(byte,4)) # [[0, 0, 200, 66], [0, 0, 200, 66], [0, 0, 200, 66]]

print(show_byte_array_string(byte,4))
# ["00000000", "00000000", "11001000", "01000010"],  # X
# ["00000000", "00000000", "11001000", "01000010"],  # Y
# ["00000000", "00000000", "11001000", "01000010"]   # Z

基础数据类型与二进制形式转换

字符串转二进制

print("a".to_ascii_buffer())   # [97]
print("a".to_utf8_buffer())	   # [97]
print("a".to_utf16_buffer())   # [97, 0]
print("a".to_utf32_buffer())   # [97, 0, 0, 0]
print("a".to_wchar_buffer())   # [97, 0]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt for WebAssembly : Application exit (SharedArrayBuffer is not defined)

用Qt开发 WebAssembly&#xff0c;放到nginx里面&#xff0c;用127.0.0.1访问没问题&#xff0c;用局域网IP访问就提示如下&#xff1a; 总结了以下两种解决办法&#xff1a; ①&#xff1a;配置 nginx http 头 [ 支持&#xff1a;WebAssembly Qt (single-threaded) ] ②&#…

关于 selinux 规则

1. 查看selinux状态 SELinux的状态&#xff1a; enforcing&#xff1a;强制&#xff0c;每个受限的进程都必然受限 permissive&#xff1a;允许&#xff0c;每个受限的进程违规操作不会被禁止&#xff0c;但会被记录于审计日志 disabled&#xff1a;禁用 相关命令&#xf…

ElevenLabs用AI为Sora文生视频模型配音 ,景联文科技提供高质量真人音频数据集助力生成逼真音效

随着Open AI公司推出的Sora文生视频模型惊艳亮相互联网&#xff0c;AI语音克隆创企ElevenLabs又为Sora的演示视频生成了配音&#xff0c;所有的音效均由AI创造&#xff0c;与视频内容完美融合。 ElevenLabs的语音克隆技术能够从一分钟的音频样本中创建逼真的声音。为了实现这一…

LVS集群 ----------------(直接路由 )DR模式部署

一、LVS集群的三种工作模式 lvs-nat&#xff1a;修改请求报文的目标IP,多目标IP的DNAT lvs-dr&#xff1a;操纵封装新的MAC地址&#xff08;直接路由&#xff09; lvs-tun&#xff1a;隧道模式 lvs-dr 是 LVS集群的 默认工作模式 NAT通过网络地址转换实现的虚拟服务器&…

Ubuntu 22.04修改静态ip

1. 备份原网络配置文件 # 配置文件名称因机器设置有异 cd /etc/netplan cp 01-network-config.yaml 01-network-config.yaml.bak# 文件内容如下 network:version: 2renderer: NetworkManager2. 修改配置文件 使用 ipconfig 命令查看网络信息&#xff0c;ip addr 命令也可 我这…

【S32DS报错】-8-调用初始化函数Port_Init后,S32DS断开与调试器PEmicro/J-Link的连接,无法调试Debug(基于MCAL)

问题背景&#xff1a; 在S32DS IDE中&#xff0c;调用初始化函数Port_Init后&#xff0c;S32DS断开与调试器PEmicro / J-Link的连接&#xff0c;无法调试Debug&#xff1a; 问题原因&#xff1a; 调用初始化函数Port_Init时&#xff0c;MCU的JTAG接口被初始化&#xff0c;导致…

Echarts 配置项 series 中的 data 是多维度

文章目录 需求分析 需求 如下图数据格式所示&#xff0c;现要求按照该格式进行绘制折线图 分析 在绘制折线图时&#xff0c;通常我们的 series 中的 data 数据是这样的格式 option {title: {text: Stacked Area Chart},tooltip: {trigger: axis,axisPointer: {type: cross…

紧握时代契机链接亿万家庭 创维汽车2024全球经销商大会圆满召开

3月6日&#xff0c;以“极致 见新境”创维汽车2024全球经销商大会在徐州隆重举行。徐州经开区管委会副主任季洪志&#xff0c;缅甸驻华大使馆商务参赞 Win Myat Aung&#xff0c;法国中小企业联盟主席 Xavier Michon-Lehnebach&#xff0c;创维集团、创维汽车创始人黄宏生&…

【项目】图书管理系统

目录 前言&#xff1a; 项目要求&#xff1a; 知识储备&#xff1a; 代码实现&#xff1a; Main&#xff1a; Books包&#xff1a; Book&#xff1a; BookList&#xff1a; Operate包&#xff1a; Operate: addOperate: deleteOperate: exitOperate: findOperate:…

Python与FPGA——膨胀腐蚀

文章目录 前言一、膨胀腐蚀二、Python实现腐蚀算法三、Python实现膨胀算法四、Python实现阈值算法五、FPGA实现腐蚀算法总结 前言 腐蚀是指周围的介质作用下产生损耗与破坏的过程&#xff0c;如生锈、腐烂等。而腐蚀算法也类似一种能够产生损坏&#xff0c;抹去部分像素的算法。…

代码随想录算法训练营第13天

239. 滑动窗口最大值 &#xff08;一刷至少需要理解思路&#xff09; 方法&#xff1a;暴力法 &#xff08;时间超出限制&#xff09; 注意&#xff1a; 代码&#xff1a; class Solution { public:vector<int> maxSlidingWindow(vector<int>& nums, int k…

掌握 Vue3、Vite 和 SCSS 实现一键换肤的魔法步骤

前言 一个网站的换肤效果算是一个比较常见的功能&#xff0c;尤其是在后台管理系统中&#xff0c;我们几乎都能看到他的身影&#xff0c;这里给大家提供一个实现思路。 搭建项目 vitevue3搭建项目这里就不演示了&#xff0c;vite官网里面讲得很清楚。 注&#xff1a;这里使…

【YOLO v5 v7 v8 v9小目标改进】辅助超推理SAHI:分而治之,解决高分辨率图像中小物体检测的问题

辅助超推理SAHI&#xff1a;分而治之&#xff0c;解决高分辨率图像中小物体检测的问题 设计思路结构小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改YOLO v9 魔改 论文&#xff1a;https://arxiv.org/pdf/2202.06934.pdf 代码&#xff1a;https://github.com/obss/sahi 设计思…

Java+SpringBoot+Vue+MySQL:农业管理新篇章

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

Git基础知多少

什么是Git Git 是分布式版本控制系统&#xff08;DVCS&#xff09;。它可以跟踪文件的更改&#xff0c;并允许你恢复到任何特定版本的更改。与 SVN 等其他版本控制系统&#xff08;VCS&#xff09;相比&#xff0c;其分布式架构具有许多优势&#xff0c;一个主要优点是它不依赖…

本地知识库搭建成功后,企业效率真的翻倍了

在如今这个快节奏的信息时代&#xff0c;对企业来说&#xff0c;拥有一套高效的知识管理系统早已不再是选项&#xff0c;而是必要。而本地知识库&#xff0c;它这个集信息存储、管理和查询于一体的平台&#xff0c;不仅改变了公司信息资源共享的方式&#xff0c;还帮助进一步提…

DataLoader

import torchvision from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter# 准备的测试数据集 数据放在了CIFAR10文件夹下test_data torchvision.datasets.CIFAR10("./CIFAR10",trainFalse, transformtorchvision.transfor…

Flutter性能优化

性能分析工具 &#xff08;1&#xff09;performance overlay 开启performance overlay后&#xff0c;Flutter APP上将显示一个展示一个浮层&#xff0c;浮层中会实时展示当前的UI线程及Raster线程的运行情况。如果都是蓝色竖条&#xff0c;说明界面运行流畅&#xff0c;否则则…

Conda快速安装的解决方法(Mamba安装)

如果你的Conda安装了&#xff0c;你可能会发现一个问题&#xff0c;就是使用Conda install 安装某个软件时&#xff0c;会特别慢&#xff0c;这时候呢&#xff1f;你会上网去搜&#xff0c;然后大家解决的方法呢。一是告诉你镜像可以下载快一点&#xff0c;二是&#xff0c;Mam…

华为OD机试 - 疫情扩散时间计算 - 矩阵(Java 2024 C卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&am…