本篇笔记整理自 Brackeys 的 YouTube 视频教程笔记和 Godot Engine (4.x) 简体中文文档
- GDScript Tutorial:How to program in Godot - GDScript Tutorial - YouTube
- GDScript Tutorial with 中文字幕:Brackeys- How to program in Godobilibili
- Docs
- Others:
1 Syntax
1.0.1 Modifying nodes
$ is short for get_node()
@export var my_node: Sprite2D
@onready var weapon = $Player/Weapon
func _ready(): # called by engine
$Label.text = "Hello, world!"
1.0.2 Input
输入示例 — Godot Engine (4.x) 简体中文文档
func _input()
if event.is_action_pressed("my_action"):
jump()
1.0.3 Variables
var health = 100 # dynamic typing
var health: int = 100 # static typing, this variable wiil always stay an integer
var health := 100 # inferred typing
@export var health := 100 # allow us to set it using the inspector
const GRAVITY = -9.81 # use CONSTANT_CASE
func _ready():
heatlth += 10
heatlth -= 10
heatlth *= 10
heatlth /= 10
print("Health: "+ str(health))
注意 scope(作用域)
1.0.4 If statements
if x != y or y >= z:
pass
elif y != z:
pass
else:
print("haha")
1.0.5 Data types
boolintfloatstringVector2: stores two floats, x and yVector3: stores three floats, x y z
var position = Vector3(1,2,3)
position.x += 2
1.0.6 Functions
func add(num1: int, num2: int) -> int:
var result = num1 + num2
return result
1.0.7 Random numbers
randf()gives a random number between 0 and 1randf_range(from, to): gives a random floating-point number number between from and torand_irange(int1, int2): gives a random integer number between int1 and int2
You can also set a fixed random seed instead
using seed()
1.0.8 shuffle bag
我们希望随机挑选水果. 然而, 每次选择水果时依靠随机数生成会导致分布不那么 均匀 . 如果玩家足够幸运(或不幸), 他们可能会连续三次或更多次得到相同的水果.
你可以使用 shuffle bag 模式来实现。它的工作原理是在选择数组后从数组中删除一个元素。多次选择之后,数组会被清空。当这种情况发生时,就将数组重新初始化为默认值。
var _fruits = ["apple", "orange", "pear", "banana"]
# A copy of the fruits array so we can restore the original value into `fruits`.
var _fruits_full = []
func _ready():
randomize()
_fruits_full = _fruits.duplicate() # deep copy
_fruits.shuffle()
for i in 100:
print(get_fruit())
func get_fruit():
if _fruits.is_empty():
# Fill the fruits array again and shuffle it.
_fruits = _fruits_full.duplicate()
_fruits.shuffle()
# Get a random fruit, since we shuffled the array,
# and remove it from the `_fruits` array.
var random_fruit = _fruits.pop_front()
# Prints "apple", "orange", "pear", or "banana" every time the code runs.
return random_fruit
1.0.9 Arrays
var array = []
var items: Array[String] = ["Knife", "Potion"]
items.append("Sword")
items[1] = "Damaged Knife"
1.0.10 Loops
# for loop
for item in items:
print(item)
# while loop
while true: # DO NOT CREATE INFINIT LOOP!
learn()
1.0.11 Dictionaries
key value pairs
var my_dict = {}
var employees = {
"Jim": {"Salary":85, "Gender": "Male"},
"Pam": {"Salary":80, "Gender": "Female"},,
}
players["Dwight"] = {"Salary":87, "Gender": "Male"}
print(employees["Jim"])
for employee in employees:
print(employee + "'s salary:" + str(employees[employee]["Salary"] ))
1.0.12 Enums
枚举的成员是常量,所以大写
enum Suits { HEART,CLUB,DIAMOND,SPADE }
var card1 = Suit.CLUB
@export var card_suit: Suits
func _ready():
if card1 == Suit.CLUB
print("Club A")
最好将枚举的每个项写在单独的一行
enum Element {
EARTH,
WATER,
AIR,
FIRE,
}
1.0.13 Match statements
func _ready():
match Suits:
Suits.HEART:
print("Heart")
Suits.CLUB:
print("Club")
_:
print("Which suit is this card?")
1.0.14 Signals
最好用过去时态来命名信号。
func _on_button_pressed():
pass
signal leveled_up(msg)
var xp := 0
for i in 8:
xp += 5
if xp >= 20:
leveled_up.emit("DING!")
func _ready():
leveled_up.connect(_on_leveled_up) # connect without inspector
leveled_up.disconnect(_on_leveled_up)
func _on_leveled_up(msg):
print(msg)
1.0.15 Setter and getter
GDScript-setter and getter set(value) 是变量的 setter 方法,用来控制变量被赋值时的行为。
var health := 100
set(value):
health = clamp(value, 0, 100)
其中 clamp(value, 0, 100) 将传入的 value 限制在 0 到 100
的范围内。
类似于 set 方法,get 方法用来控制变量在被读取时的行为,更常用于转换值:
var chance := 100
var chance_pct: int:
get:
return chance * 100
set(value):
chance = float(value)/100
Unlike setget in previous Godot
versions, set and get methods
are always called (except as noted below), even when
accessed inside the same class (with or without prefixing
with self.). This makes the behavior consistent. If you
need direct access to the value, use another variable for direct access
and make the property code use that name.
1.0.16 Classes
https://www.bilibili.com/video/BV1mH4y1g7e5?t=3072.9 Godot 所有内置节点都是类
class_name Charactor
extends Node
1.0.17 Inner classes
var chest := Equipment.new()
var legs := Equipment.new()
func _ready():
chest.armor = 20
# Inner class
class Equipment:
var armor := 10
var weight := 5
1.0.18 Composition
bitlytic How you can easily make your code simpler in Godot 4
1.1 Practices
1.1.1 Call down, signal up
Node communication 在层次结构中,节点可以调用位于其下方的节点上的函数,但反之则不然。
1.1.2 Memory management
1.1.3 Style
代码顺序:
01. @tool
02. class_name
03. extends
04. # docstring
05. signals
06. enums
07. constants
08. @export variables
09. public variables
10. private variables
11. @onready variables
12. optional built-in virtual _init method
13. optional built-in virtual _enter_tree() method
14. built-in virtual _ready method
15. remaining built-in virtual methods
16. public methods
17. private methods
18. subclasses