返回介绍

Godot Engine:用自动加载(AutoLoad) 实现单例模式(Singleton Pattern)

发布于 2025-04-26 18:34:24 字数 4253 浏览 0 评论 0 收藏

自动加载(AutoLoad) 是 Godot Engine 一个特有的并且设计非常巧妙的机制。

什么是单例模式(Singleton Pattern)

上世纪 90 年代由 Gof(Gang of Four,四位软件界大牛) 合写了一本《Design Patterns: Elements of Reusable Object-Oriented Software》(设计模式:可复用的面向对象软件元素),该书包含 23 种解决编程时特定问题的“套路”,也就是所谓的“设计模式”。这本书如同武林秘籍《降龙十八掌》,被后辈程序员们奉为必修经典之一。

单例模式就是这 23 种经典设计模式之一。它要解决两个问题:

  1. 某个类(Class) 在整个系统中有且只有一个实例。
  2. 这个实例可以在整个系统被访问。

单例模式是游戏开发最最常用的设计模式之一,比如:各种资源管理类,核心数据类等等的实现大都需要这种“单例类”。

用 GDScript 无法实现单例模式

下面是一个 C#版本的单例模式实现(其它语言版本也大体相似):

public  class  Singleton { 
    private  static  Singleton instance = null ; 

    private  Singleton(){ 
    } 

    public  static  Singleton Instance { 
        get { 
            if  (instance == null){ 
                instance =  new  Singleton(); 
            } 
            return  instance; 
        } 
    } 
}

实现单例模式的核心要素之一是:“需要一个 静态变量 指向该类唯一的实例并作为判定有无实例的标志位”。
然而,GDScript—这个简单粗暴的语言—压根儿就没有 静态变量 这种东西!!!刚接触 Godot 的时候,这个事实简直无法接受。后来才知道,这个由微型团队开发的游戏引擎,并没有自不量力地企图开发一种“高大全”的脚本语言,而采用了一种“语言不够引擎来凑”的设计策略,用所谓自动加载的引擎机制帮你完成了实现单例模式的需求。这种策略使得 GDScript 的语言内核足够精简从而容易实现和维护,同时也使它更加容易上手。下面我们来体验一下,用“自动加载”如何简单优雅地实现单例模式。

用自动加载(AutoLoad) 实现单例模式

在 Godot 中我们不仅可以“单例化”一个类,还可以“单例化”一个配置好的场景。

单例类
1. 定义要单例化的类

假设,我们想把下面这个存储游戏的数据的类单例化。

#GameData.gd
extends Node
var score = 0
var hp = 5
var level = 6
2. 设置自动加载

打开 项目设置>自动加载

把“GameData.gd”脚本添加 自动加载


注意:这个名称就是你在程序中要调用的变量名

3. 测试

新建一个场景

#SingletonTest.gd
extends Node
func _ready():
	print("Player HP: " + str(GameData.hp))

运行一下,输出结果

Player HP: 5

就这么简单地实现了。

单例场景
1. 定义要单例化的场景


下面是场景根节点"AudioManager"上的脚本:

#AudioManager.gd
extends Node
func play(name : String):
	var sfx = find_node(name)
	if sfx is AudioStreamPlayer:
		sfx.play()
2. 设置自动加载

打开 项目设置>自动加载

注意:这次我们要添加到 自动加载 中的不是“AudioManager.gd”脚本,而是挂接了该脚本的“AudioManager.tscn”场景。

3. 测试
#ScoreArea.gd
extends Area2D
func _ready():
	connect("body_exited",self,"_on_body_exited")
func _on_body_exited(_body):#当有物体穿过
	if _body.name == "Bird":#并且判断该物体为小鸟时
		AudioManager.play("sfx_point")#音效

这样,当小鸟穿越过一对柱子,就可以播放得分的音效了。

PS:自动加载的实例(场景)到底在哪?

当我们运行游戏的时候,在 远程 窗口下可以看到游戏运行时场景树的状态,单例的类实例和场景,被自动加载以后作为场景树的 root 的直接子节点,而且会出现在其它节点的上方。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。