在 Godot 中应用面向对象原则
1. Godot 引擎的可复用对象
Godot 引擎主要提供了两种创建可复用对象的方式:脚本和场景。严格来说,这两种方式都没有真的在底层定义类。
尽管如此,在许多使用 Godot 的最佳方法中,依然会将面向对象的编程原则应用到脚本和场景中。
2. 脚本的面向对象
2.1 Godot 脚本
引擎提供了内置的类,如 Node 。你可以使用脚本扩展这些类来创建派生类型。
脚本本身在 Godot 眼里是一种“资源文件”(就像图片、声音一样),它的作用是一份“说明书”,用来告知引擎在某一个内置类的基础上执行一系列初始化。
2.2 Godot 自定义类的原理
Godot 内部有一个叫 ClassDB 的数据库注册了类的数据,该数据库让我们可以在运行时访问类的信息。
ClassDB 包含有关类的信息,例如:属性、方法、常量、信号。
当对象在执行访问属性或调用方法等操作时,它就会检查 ClassDB 中对象和对象基类的记录,以确定对象是否支持该操作。
将 Script 附加到你的对象上,可以扩展 ClassDB 中该对象的方法、属性和信号。
2.3 没有 extends 的情况
在 GDScript 里,第一行通常是 extends 。
如果脚本没有使用 extends 关键字,则会隐式地继承引擎的基础 RefCounted 类(一种最基础的、会自动销毁的内存管理对象)。这种脚本你可以用来写纯逻辑(比如计算伤害公式),但不能挂在场景树的节点上,因为节点必须继承自 Node 类型。
3. 场景的面向对象
3.1 场景与类的相似与关联
场景是可复用、可实例化、可继承的节点组。
场景的行为与类有很多相似之处,所以把场景看成一个类也是合理的。
3.2 场景是类的一部分的情况
如果为场景搭配一个带有脚本的根节点,并在脚本中使用这个场景下的节点。
场景就是对附着在根节点上的脚本的扩展,所以你也可以将其解释为类的一部分。根节点的脚本是逻辑,子节点是数据和组件。把它们打包在一起,就是一个完整的面向对象单元。
场景的内容有助于定义:脚本可使用哪些节点、它们是如何组织的、它们是如何初始化的、它们彼此之间有什么信号连接。
为什么这些对组织场景很重要?因为场景的实例都是对象。因此,许多适用于书面代码的面向对象原则也适用于场景:单一职责、封装等。