GDScript 是 Godot 引擎的专属高级编程语言。它是一种面向对象、命令式且渐进类型化(Gradually Typed)的语言。其设计初衷并非追求通用性,而是为了最大化游戏开发效率,与 Godot 的节点系统(Node System)实现无缝集成。如果你熟悉 Python,你会发现 GDScript 的语法非常亲切,它同样使用缩进来定义代码块。
理解 GDScript 的设计哲学有助于编写出更符合引擎预期的代码。其核心设计目标包括以下几点:
var a = 10),也可以像编写 C# 一样指定静态类型(var a: int = 10)。编译器会根据类型提示进行优化,并在开发时捕获潜在错误。extends),但 Godot 引擎鼓励通过场景树(Scene Tree)将多个节点组合在一起,而不是构建深层的继承链。每个脚本文件本质上就是一个类。GDScript 的基础语法非常直观。变量使用 var 关键字声明。
# 动态类型声明
var player_name = "Hero"
var score = 0
var is_alive = true
# 静态类型声明(推荐,性能更好,提示更全)
var health: int = 100
var speed: float = 12.5
var position: Vector2 = Vector2(0, 0)
GDScript 提供了丰富的内置类型,主要分为基础类型和引擎特有类型:
| 类型 | 描述 | 示例 |
|---|---|---|
int |
整数(64位) | var level = 1 |
float |
浮点数(小数) | var gravity = 9.8 |
String |
字符串文本 | var text = "Hello" |
bool |
布尔值(真/假) | var active = false |
Vector2 |
二维向量 (x, y),用于 2D 坐标 | var velocity = Vector2(10, 0) |
Array |
有序列表,可容纳不同类型 | var inventory = ["sword", "potion"] |
Dictionary |
键值对集合 | var stats = {"hp": 100, "mp": 50} |
函数是组织代码的基本单位。GDScript 使用 func 关键字定义函数。
# 基础函数定义
func greet(name):
print("Hello, " + name + "!")
# 带有类型提示和默认参数的函数
func calculate_damage(base_damage: int, multiplier: float = 1.0) -> int:
return int(base_damage * multiplier)
# 调用函数
func _ready():
greet("Player")
var dmg = calculate_damage(10, 1.5)
Godot 引擎会在特定时机自动调用以下函数,我们称之为虚拟函数或生命周期函数:
_ready(): 当节点进入场景树时调用。用于初始化变量、获取子节点引用等。_process(delta): 每一帧调用。用于处理需要连续更新的逻辑(如非物理移动)。参数 delta 是距离上一帧的时间(秒)。_physics_process(delta): 每一个物理帧调用(通常比渲染帧更固定)。用于处理物理计算(如移动 CharacterBody2D)。在 GDScript 中,每一个 .gd 文件就是一个类。你可以使用 extends 关键字让一个类继承另一个类(通常是 Godot 的内置节点类型,如 Node2D, Control, RigidBody3D 等)。
# 继承自 CharacterBody2D
class_name Player
extends CharacterBody2D
# 导出变量:允许在编辑器 Inspector 面板中直接修改
@export var speed: float = 200.0
# 成员变量
var health: int = 100
func _physics_process(delta):
var direction = Vector2()
# 简单的移动逻辑
if Input.is_action_pressed("ui_right"):
direction.x += 1
if Input.is_action_pressed("ui_left"):
direction.x -= 1
velocity = direction * speed
move_and_slide()
信号是 Godot 架构中观察者模式的实现。它允许节点在发生特定事件时通知其他节点,而无需硬编码依赖关系。
# 定义一个自定义信号
signal health_changed(new_value)
func take_damage(amount: int):
health -= amount
# 发射信号
health_changed.emit(health)
下面是一个完整的脚本示例,展示了 GDScript 如何结合类型系统、生命周期、节点引用和信号来构建一个简单的玩家逻辑。
extends Area2D
# --- 属性定义 ---
@export var speed: float = 400.0
var screen_size: Vector2 # 屏幕尺寸
# --- 信号 ---
signal hit # 当玩家被击中时发射
# --- 生命周期函数 ---
func _ready():
# 隐藏玩家直到游戏开始
hide()
screen_size = get_viewport_rect().size
# --- 物理帧处理 ---
func _process(delta):
var velocity = Vector2.ZERO # 重置速度
# 输入处理
if Input.is_action_pressed("move_right"):
velocity.x += 1
if Input.is_action_pressed("move_left"):
velocity.x -= 1
if Input.is_action_pressed("move_down"):
velocity.y += 1
if Input.is_action_pressed("move_up"):
velocity.y -= 1
# 归一化对角线移动速度
if velocity.length() > 0:
velocity = velocity.normalized() * speed
# 更新位置
position += velocity * delta
# 限制在屏幕内
position.x = clamp(position.x, 0, screen_size.x)
position.y = clamp(position.y, 0, screen_size.y)
# --- 当物体进入 Area2D 区域时自动触发 ---
func _on_body_entered(body):
hide() # 玩家消失
hit.emit() # 发射被击中信号
# 必须禁用碰撞监测,否则发射信号后仍会继续触发
set_deferred("monitoring", false)
GDScript 是为了游戏开发而生的语言。它摒弃了复杂的工程化负担,将重点放在了快速迭代和直观表达上。通过掌握其类型系统、函数机制以及与 Godot 节点树的交互方式,开发者可以极其高效地将游戏创意转化为现实。对于初学者来说,它是进入游戏编程领域的最佳跳板;对于资深开发者,它提供了足够的灵活性和控制力来构建复杂的系统。
还没有人回复