Godot的GD语言 部分语法学习/复习
> func get_uri(url: String, query_params: String):
> return "%s%s%s" % [_base_uri, url, "?" + query_params if query_params else ""]
? + query_params if query_params else "" 是一个条件表达式。
如果 query_params 不为空,就返回 ? + query_params,否则返回空字符串。
?+query_params 表示 如果 query_params 不为空,就会生成带有查询参数的字符串;否则,只生成基本 URl。
三元表达式 x if condition else y 表示如果条件 condition 为真,则返回 x,否则返回 y。在你的代码中,用于在字符串中插入查询参数或者插入空字符串。
while
一般的循环通过 while 语法创建,可以使用 break 来跳出整个循环,
或者使用 continue 来跳出当前批次的循环并进入下一轮的循环当中(但会将该关键字下方所有在该循环体内的语句全部跳过):
while (expression):
statement(s)
for
若需要在数组迭代时对数组进行赋值操作,则推荐使用 for i in array.size() 来进行该操作。
for i in array.size():
array[i] = "Hello World"
循环变量只属于该循环,为其赋值并不会更改数组的值。如果循环变量是通过引用传递的对象(如节点),则仍可通过调用其方法来操作所指向的对象。
"for string in string_array:
string = "Hello World" # This has no effect
for node in node_array:
node.add_to_group("Cool_Group") # This has an effect"
这段代码是在讲解在遍历字符串数组和节点数组时的不同行为。让我们逐行解释:
for string in string_array:
string = "Hello World" # 这没有效果
在这里,代码试图遍历一个字符串数组(string_array
),并将每个字符串设为 "Hello World"。然而,这行代码实际上没有产生预期的效果。原因是在这个循环中,string
只是循环迭代过程中的一个变量,修改它并不会影响数组中的实际字符串元素。每次迭代结束时,string
都会指向数组中的下一个元素,但修改 string
本身并不会影响数组。
相比之下,下面的代码片段演示了节点数组的不同行为:
for node in node_array:
node.add_to_group("Cool_Group") # 这有效果
在这里,代码遍历了一个节点数组(node_array
),并对每个节点调用了 add_to_group("Cool_Group")
方法。这样的操作实际上对数组中的节点产生了影响,因为这里的 node
是对实际数组中节点的引用。调用 add_to_group
方法将每个节点添加到一个名为 "Cool_Group" 的组中,这会对数组中的节点产生实际的效果。
所以,总的来说,两个循环的区别在于对数组元素的修改是否会影响数组本身。在字符串数组的情况下,修改循环变量 string
不会影响数组中的元素;而在节点数组的情况下,修改循环变量 node
可能会影响数组中的节点。
使用 continue 来跳出当前批次的循环并进入下一轮的循环当中(但会将该关键字下方所有在该循环体内的语句全部跳过):
func _ready():
var A=[1,2,3,3,4]
for x in A:
if x==3:
continue
print(x)
print("Done!")
输出结果为 1 2 4
GDScript 风格指南 Godot 游戏引擎 v3.5 中文文档
行尾逗号
请在数组、字典和枚举的最后一行使用逗号。这将使版本控制中的重构更容易,Diff 也更美观,因为添加新元素时不需要修改最后一行。
良好的 :
enum Tiles {
TILE_BRICK,
TILE_FLOOR,
TILE_SPIKE,
TILE_TELEPORT,
}
糟糕的 :
enum Tiles {
TILE_BRICK,
TILE_FLOOR,
TILE_SPIKE,
TILE_TELEPORT
}
单行列表中不需要行尾逗号,因此在这种情况下不要添加它们。
良好的 :
enum Tiles {TILE_BRICK, TILE_FLOOR, TILE_SPIKE, TILE_TELEPORT}
糟糕的 :
enum Tiles {TILE_BRICK, TILE_FLOOR, TILE_SPIKE, TILE_TELEPORT,}
空白行
用两个空行包围函数和类定义
空格
请始终在运算符前后和逗号后使用一个空格。同时,请避免在字典引用和函数调用中使用多余的空格。
良好的 :
position.x = 5
position.y = target_position.y + 10
dict["key"] = 5
my_array = [4, 5, 6]
print("foo")
利用 GDScript 的文字下划线,使大数字更易读。
良好的:
var large_number = 1_234_567_890
var large_hex_number = 0xffff_f8f8_0000
var large_bin_number = 0b1101_0010_1010
Numbers lower than 1000000 generally don't need separators.
var small_number = 12345
函数与变量
函数与变量使用 snake_case 命名:
var particle_effect
func load_level():
在用户必须覆盖的虚方法、私有函数、私有变量前加一个下划线(_):
var _counter = 0
func _recalculate_path():
信号
用过去时态来命名信号:
signal door_opened
signal score_changed
我们建议按以下方式组织GDScript代码:
01. tool
02. class_name
03. extends
04. # docstring
05. signals
06. enums
07. constants
08. exported variables
09. public variables
10. private variables
11. onready variables
12. optional built-in virtual _init method
13. built-in virtual _ready method
14. remaining built-in virtual methods
15. public methods
16. private methods
优化了顺序, 使从上到下阅读代码变得容易, 帮助第一次阅读代码的开发人员了解代码的工作原理, 并避免与变量声明顺序相关的错误.
此代码顺序遵循四个经验法则:
首先是属性和信号, 然后是方法.
公共变量优先于私有变量.
虚回调出现在类的接口之前.
对象的构造和初始化函数 _init 和 _ready 在修改对象的函数之前运行.
类声明
如有必要,在后面加上 class_name。您可以使用此功能将 GDScript 文件转换为项目中的全局类型。
有效的类型有:
内置类型(Array, Vector2, int, String, 等).
引擎类(Node, Resource, Reference, 等).
常量名, 如果它们包含脚本资源(MyScript 如果声明 const MyScript = preload("res://my_script.gd")).
在同一个脚本中的其他类, 遵循作用域(如果在相同作用域内, 在 class InnerClass 中声明 class NestedClass 得到 InnerClass.NestedClass ).
脚本类使用 class_name 关键字声明.