源代码下载: learngdscript-cn.gd

GDScript 是一种动静类型的脚本语言,专门为收费开源游戏引擎 Godot 制作。 GDScript 的语法相似 Python。 它的次要长处是易于应用和与引擎深度集成。 它非常适合游戏开发。

根底

# 单行正文应用 # 号书写。"""  多行  正文  是  应用  文档字符串(docstring)  书写。"""# 脚本文件自身默认是一个类,文件名为类名,您也能够为其定义其余名称。class_name MyClass# 继承extends Node2D# 成员变量var x = 8 # 整型var y = 1.2 # 浮点型var b = true # 布尔型var s = "Hello World!" # 字符串var a = [1, false, "brown fox"] # 数组(Array) - 相似于 Python 的列表(list),                                # 它能够同时保留不同类型的变量。var d = {  "key" : "value",  42 : true} # 字典蕴含键值对。var p_arr = PoolStringArray(["Hi", "there", "!"]) # 池数组只能蕴含繁多类型。                                                  # 放入其余类型会被转换为指标类型# 内置向量类型:var v2 = Vector2(1, 2)var v3 = Vector3(1, 2, 3)# 常量const ANSWER_TO_EVERYTHING = 42const BREAKFAST = "Spam and eggs!"# 枚举enum { ZERO, ONE , TWO, THREE }enum NamedEnum { ONE = 1, TWO, THREE }# 导出的变量将在查看器中可见。export(int) var ageexport(float) var heightexport var person_name = "Bob" # 如果设置了默认值,则不须要类型注解。# 函数func foo():  pass # pass 关键字是未书写的代码的占位符func add(first, second):  return first + second# 打印值func printing():  print("GDScript ", "几乎", "棒呆了")  prints("这", "些", "字", "被", "空", "格", "分", "割")  printt("这", "些", "字", "被", "制", "表", "符", "分", "割")  printraw("这句话将被打印到零碎控制台。")# 数学func doing_math():  var first = 8  var second = 4  print(first + second) # 12  print(first - second) # 4  print(first * second) # 32  print(first / second) # 2  print(first % second) # 0  # 还有 +=, -=, *=, /=, %= 等操作符,但并没有 ++ 和 -- .  print(pow(first, 2)) # 64  print(sqrt(second)) # 2  printt(PI, TAU, INF, NAN) # 内置常量# 控制流func control_flow():  x = 8  y = 2 # y 最后被设为一个浮点数,        # 但咱们能够利用语言提供的动静类型能力将它的类型变为整型!  if x < y:    print("x 小于 y")  elif x > y:    print("x 大于 y")  else:    print("x 等于 y")  var a = true  var b = false  var c = false  if a and b or not c: # 你也能够用 &&, || 和 !    print("看到这句阐明下面的条件判断为真!")  for i in range(20): # GDScript 有相似 Python 的 range 函数    print(i) # 所以这句将打印从 0 到 19 的数字  for i in 20: # 与 Python 略有不同的是,你能够间接用一个整型数开始循环    print(i) # 所以这行代码也将打印从 0 到 19 的数字  for i in ["two", 3, 1.0]: # 遍历数组    print(i)  while x > y:    printt(x, y)    y += 1  x = 2  y = 10  while x < y:    x += 1    if x == 6:      continue # continue 语句使 x 等于 6 时,程序跳过这次循环前面的代码,不会打印 6。    prints("x 等于:", x)    if x == 7:      break # 循环将在 x 等于 7 处跳出,后续所有循环不再执行,因而不会打印 8、9 和 10  match x:    1:      print("match 很像其余语言中的 switch.")    2:      print("然而,您不须要在每个值之前写一个 case 关键字。")    3:      print("此外,每种状况都会默认跳出。")      break # 谬误!不要在 match 里用 break 语句!    4:      print("如果您须要跳过后续代码,这里也应用 continue 关键字。")      continue    _:      print("下划线分支,在其余分支都不满足时,在这里书写默认的逻辑。")  # 三元运算符 (写在一行的 if-else 语句)  prints("x 是", "正值" if x >= 0 else "负值")# 类型转换func casting_examples():  var i = 42  var f = float(42) # 应用变量构造函数强制转换  var b = i as bool # 或应用 as 关键字# 重载函数# 通常,咱们只会重载以下划线结尾的内置函数,# 但实际上您能够重载简直任何函数。# _init 在对象初始化时被调用。# 这是对象的构造函数。func _init():  # 在此处初始化对象的外部属性。  pass# _ready 在脚本节点及其子节点进入场景树时被调用。func _ready():  pass# _process 在每一帧上都被调用。func _process(delta):  # 传递给此函数的 delta 参数是工夫,即从上一帧到以后帧通过的秒数。  print("Delta 工夫为:", delta)# _physics_process 在每个物理帧上都被调用。# 这意味着 delta 应该是恒定的。func _physics_process(delta):  # 应用向量加法和乘法进行简略挪动。  var direction = Vector2(1, 0) # 或应用 Vector2.RIGHT  var speed = 100.0  self.global_position += direction * speed * delta  # self 指向以后类的实例# 重载函数时,您能够应用 . 运算符调用父函数# like here:func get_children():  # 在这里做一些额定的事件。  var r = .get_children() # 调用父函数的实现  return r# 外部类class InnerClass:  extends Object  func hello():    print("来自外部类的 Hello!")func use_inner_class():  var ic = InnerClass.new()  ic.hello()  ic.free() # 能够自行开释内存

拜访场景树中其余节点

extends Node2Dvar sprite # 该变量将用来保留援用。# 您能够在 _ready 中获取对其余节点的援用。func _ready() -> void:  # NodePath 对于拜访节点很有用。  # 将 String 传递给其构造函数来创立 NodePath:  var path1 = NodePath("path/to/something")  # 或者应用 NodePath 字面量:  var path2 = @"path/to/something"  # NodePath 示例:  var path3 = @"Sprite" # 相对路径,以后节点的间接子节点  var path4 = @"Timers/Firerate" # 相对路径,子节点的子节点  var path5 = @".." # 以后节点的父节点  var path6 = @"../Enemy" # 以后节点的兄弟节点  var path7 = @"/root" # 绝对路径,等价于 get_tree().get_root()  var path8 = @"/root/Main/Player/Sprite" # Player 的 Sprite 的绝对路径  var path9 = @"Timers/Firerate:wait_time" # 拜访属性  var path10 = @"Player:position:x" # 拜访子属性  # 最初,获取节点援用能够应用以下办法:  sprite = get_node(@"Sprite") as Sprite # 始终转换为您冀望的类型  sprite = get_node("Sprite") as Sprite # 这里 String 被隐式转换为 NodePath  sprite = get_node(path3) as Sprite  sprite = get_node_or_null("Sprite") as Sprite  sprite = $Sprite as Spritefunc _process(delta):  # 当初咱们就能够在别处应用 sprite 里保留的援用了。  prints("Sprite 有一个全局地位 ", sprite.global_position)# 在 _ready 执行之前,应用 onready 关键字为变量赋值。# 这是一种罕用的语法糖。onready var tween = $Tween as Tween# 您能够导出这个 NodePath,以便在查看器中给它赋值。export var nodepath = @""onready var reference = get_node(nodepath) as Node

信号(Signals)

信号系统是 Godot 对观察者编程模式的实现。例子如下:

class_name Player extends Node2Dvar hp = 10signal died() # 定义一个信号signal hurt(hp_old, hp_new) # 信号能够带参数func apply_damage(dmg):  var hp_old = hp  hp -= dmg  emit_signal("hurt", hp_old, hp) # 发出信号并传递参数  if hp <= 0:    emit_signal("died")func _ready():  # 将信号 "died" 连贯到 self 中定义的 _on_death 函数  self.connect("died", self, "_on_death")func _on_death():  self.queue_free() # 死亡时销毁 Player

类型注解

GDScript 能够选择性地应用动态类型。extends Node

var x: int # 定义带有类型的变量var y: float = 4.2var z := 1.0 # 应用 := 运算符依据默认值推断类型onready var node_ref_typed := $Child as Nodeexport var speed := 50.0const CONSTANT := "Typed constant."func _ready() -> void:  # 此函数不返回任何货色  x = "string" # 谬误!不要更改类型!  returnfunc join(arg1: String, arg2: String) -> String:  # 此函数承受两个 String 并返回一个 String。  return arg1 + arg2func get_child_at(index: int) -> Node:  # 此函数承受一个 int 并返回一个 Node  return get_children()[index]signal example(arg: int) # 谬误!信号不能承受类型参数!

延展浏览

  • Godot's Website
  • Godot Docs
  • Getting started with GDScript
  • NodePath
  • Signals
  • GDQuest
  • GDScript.com

有倡议?或者发现什么谬误?在Github上开一个issue,或者发动pull request!

原著Wichamir,并由0个好心人批改。
Translated by: ShiftWatchOut
© 2022 Wichamir
本作品采纳 CC BY-SA 3.0 协定进行许可。