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

news2025/4/11 17:42:05

概述

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]

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LVS集群(Linux Virtual server)

集群概念lvs模型lvs调度算法lvs实现lvs高可用性&#xff0c;负载均衡 1 集群和分布式 系统性能扩展方式&#xff1a; Scale UP&#xff1a;垂直扩展&#xff0c;向上扩展,增强&#xff0c;性能更强的计算机运行同样的服务 升级单机的硬件设备Scale Out&#xff1a;水平扩展…

【DP】蓝桥杯第十三届-费用报销

#include<iostream> #include<algorithm> #include<cstring> #include<set> #include<queue> using namespace std; const int N1010; int dp[N][5010];//dp[i][j]:选到第i个物品是否能取到价值j&#xff1b; int month[13]{0,31,28,31,30,31,30…

Unity3D学习之XLua实践——背包系统

文章目录 1 前言2 新建工程导入必要资源2.1 AB包设置2.2 C# 脚本2.3 VSCode 的环境搭建 3 面板拼凑3.1 主面板拼凑3.2 背包面板拼凑3.3 格子复合组件拼凑3.4 常用类别名准备3.5 数据准备3.5.1 图集准备3.5.2 json3.5.3 打AB包 4 Lua读取json表及准备玩家数据5 主面板逻辑6 背包…

仓储管理系统(WMS) 的研发历程-PRD撰写

题外话&#xff1a;PRD的展现形式有多种&#xff0c;有的人喜欢在axure上直接做产品描述&#xff0c;觉得word较为过时&#xff0c;有的人认为axure不专业&#xff0c;任何展现形式都无可厚非&#xff0c;重要的达到PRD的目的&#xff0c;PRD的目标是让团队知道需求实现细节&am…

[数据结构初阶]队列

鼠鼠我呀&#xff0c;今天写一个基于C语言关于队列的博客&#xff0c;如果有兴趣的读者老爷可以抽空看看&#xff0c;很希望的到各位老爷观点和点评捏&#xff01; 在此今日&#xff0c;也祝各位小姐姐女生节快乐啊&#xff0c;愿笑容依旧灿烂如初阳&#xff0c;勇气与童真永不…

2024/3/7—2575. 找出字符串的可整除数组

代码实现&#xff1a; int* divisibilityArray(char *word, int m, int *returnSize) {int n strlen(word);int *res (int*)malloc(sizeof(int) * n);long cur 0;for (int i 0; i < n; i) {cur (cur * 10 (word[i] - 0)) % m;res[i] (cur 0) ? 1 : 0;}*returnSize …

[Unity实战]使用NavMeshAgent做玩家移动

其实除了Character Controller, Rigidbody&#xff0c;我们还可以使用NavMeshAgent去做。这么做的好处是能避免玩家去莫名其妙的地方&#xff08;毕竟基于烘焙过的导航网格&#xff09;&#xff0c;一般常见于元宇宙应用和mmo。 根据Unity手册&#xff0c;NavMeshAgent 也有和…

考研新手小白,必须提前了解的考研常识

关于考研需要知道的一些常识&#xff1a; 在大三上学期开学&#xff0c;通常是在9月左右&#xff0c;开始考虑选择学校和专业&#xff0c;购买相关资料&#xff0c;收集相关信息&#xff0c;启动研究生考试的复习计划。 接下来的年度&#xff08;即第四学年制的大四学期&…

C语言数据类型详解及相关题——各种奇奇怪怪的偏难怪

文章目录 一、C语言基本数据类型溢出 二、存储原理符号位原码反码补码补码操作的例子 三、赋值中的类型转换常见返回类型——巨坑总结 一、C语言基本数据类型 溢出 因为数据范围&#xff08;即存储单元的位的数量&#xff09;的限制&#xff0c;可以表达的位数是有限的。 溢出…

AtCoder Beginner Contest 343(A,B,C,D,E,F)

比赛链接 CE是暴力&#xff0c;D是数据结构题&#xff0c;F是线段树。这场的E比较有意思&#xff0c;其他的感觉有点水。 A - Wrong Answer 题意&#xff1a; 给你两个数 A , B A,B A,B ( 0 ≤ A , B ≤ 9 ) (0\le A,B\le 9) (0≤A,B≤9)&#xff0c;返回一个个位数&#…

手机app制作商用系统软件开发

手机端的用户占比已经超过了电脑端的用户量&#xff0c;企业想要发展手机端的业务就必须拥有自己的app软件&#xff0c;我们公司就是专门为企业开发手机软件的公司&#xff0c;依据我们多年的开发经验为大家提供在开发app软件的时候怎么选择开发软件的公司。 手机app制…

spring-jpa

一、介绍 1.1ORM 1.2 Java Persistence API 放在javaee版本 优点 支持持久化复杂的Java对象&#xff0c;简化Java应用的对象持久化开发支持使用JPQL语言进行复杂的数据查询使用简单&#xff0c;支持使用注解定义对象关系表之间的映射规范标准化&#xff0c;由Java官 方统一规…

阿里云服务器购买搭建

1.首先在阿里云官网购买ESC云服务器 2.在域名处&#xff0c;购买域名&#xff0c;申请免费的SSL证书&#xff0c;但是这个证书需要去备案&#xff0c;这个周期比较长。 3.登录你的服务器就可以安装你需要的环境&#xff0c;进行开发&#xff0c;当然使用docker很好用。 以下…

【开源物联网平台】FastBee认证方式和MQTT主题设计

&#x1f308; 个人主页&#xff1a;帐篷Li &#x1f525; 系列专栏&#xff1a;FastBee物联网开源项目 &#x1f4aa;&#x1f3fb; 专注于简单&#xff0c;易用&#xff0c;可拓展&#xff0c;低成本商业化的AIOT物联网解决方案 目录 一、接入步骤 1.1 设备认证 1.2 设备交…

【Leetcode】3028.边界上的蚂蚁

题目描述 思路 题目中要求我们返回 蚂蚁返回到边界的次数。简单来想&#xff0c;就是蚂蚁原来的位置的一维坐标为0&#xff0c;然后经过&#xff0c;若干次移动&#xff0c;统计有几次坐标再次变为0的个数。 我们利用前缀和&#xff0c;像定义一个数组&#xff0c;算出前缀和数…

贪心算法详解及机器人运动应用Demo

一、引言 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最好或最优的算法。贪心算法在有最优子结构的问题中尤为有效。今天&#xff0c;我们将通过一个机器人运动的Demo来详细解析贪心算…

网络编程作业day7

作业项目&#xff1a;基于UDP的聊天室 服务器代码&#xff1a; #include <myhead.h>//定义客户信息结构体 typedef struct magtye {char type; //消息类型char name[100]; //客户姓名char text[1024]; //客户发送聊天信息 }msg_t;//定义结构体存储…

基于YOLOv5的驾驶员疲劳驾驶行为​​​​​​​检测系统

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文主要内容:详细介绍了疲劳驾驶行为检测整个过程&#xff0c;从数据集到训练模型到结果可视化分析。 博主简介 AI小怪兽&#xff0c;YOLO骨灰级玩家&#xff0c;1&#xff09;YOLOv5、v7、v8优化创新&#xff0c;轻松涨点和模型轻量…

Java特性之设计模式【过滤器模式】

一、过滤器模式 概述 ​ 过滤器模式&#xff08;Filter Pattern&#xff09;或标准模式&#xff08;Criteria Pattern&#xff09;是一种设计模式&#xff0c;这种模式允许开发人员使用不同的标准来过滤一组对象&#xff0c;通过逻辑运算以解耦的方式把它们连接起来。这种类型的…

几何工具的使用

Geometry - Creation 创建几何 CogCreateCircleTool&#xff1a;创建圆CogCreateEllipseTool:创建椭圆CogCreateLineBisectPointsTool&#xff1a;带有两个点的平行线CogCreateLineParallelTool:在某一点创建某条线的平行线CogCreateLinePerpendicularTool:在某一点创建某条线…