- 出道即巅峰,先做个盈利千万的小项目
- 新建 Godot 项目
- Godot 界面介绍
- FlappyBird:1.Hello World
- FlappyBird:2.坠落吧,小鸟
- FlappyBird:3.在哪坠落就在哪飞起来
- FlappyBird:4. 无限地面
- FlappyBird:4.1 无限地面之 Godot 青年 (AnimationPlayer) 版
- FlappyBird:4.2 无限地面之普通青年版
- FlappyBird:4.3 无限地面之文艺青年(shader) 版
- FlappyBird:5.1 无尽水管子滚滚来(一)
- Godot Engine:5 种碰撞体以及 RigidBody 的 4 种模式
- Godot Engine:碰撞和碰撞检测的简单实例(RigidBody2D 与 Area2D 碰撞)
- Godot Engine:碰撞和碰撞检测的简单实例(RigidBody2D 与 StaticBody2D 碰撞)
- FlappyBird:5.2 无尽水管子滚滚来(二)
- Godot Engine:Timer 节点使用范例
- FlappyBird:6 来点 MUSIC(音效系统)
- Godot Engine:用自动加载(AutoLoad) 实现单例模式(Singleton Pattern)
- FlappyBird:7 心里有数(计分系统)
- Godot Engine:本地数据存取的帮助类(加密/非加密)
- FlappyBird:8 让数据说话(显示分数)
- Godot Engine:如何使用外部字体和 Label 节点制作一个计时器
- FlappyBird:9.1 天下没有不 OVER 的 GAME(上)
- Godot Engine:两行代码实现观察者模式(Observer Pattern),就问你服不服?
- FlappyBird:9.2 天下没有不 OVER 的 GAME(下)
- FlappyBird:10 大不了从头再来(新局启动)
- Godot Engine:用 Call Method Track(方法回调轨道)实现动画回调
- FlappyBird:11 番外篇:罗永浩都抖音了,要不咱们也抖一抖?(屏幕震动)
- Godot Engine:屏幕振动效果的实现
Godot Engine:用自动加载(AutoLoad) 实现单例模式(Singleton Pattern)
自动加载(AutoLoad) 是 Godot Engine 一个特有的并且设计非常巧妙的机制。
什么是单例模式(Singleton Pattern)
上世纪 90 年代由 Gof(Gang of Four,四位软件界大牛) 合写了一本《Design Patterns: Elements of Reusable Object-Oriented Software》(设计模式:可复用的面向对象软件元素),该书包含 23 种解决编程时特定问题的“套路”,也就是所谓的“设计模式”。这本书如同武林秘籍《降龙十八掌》,被后辈程序员们奉为必修经典之一。
单例模式就是这 23 种经典设计模式之一。它要解决两个问题:
- 某个类(Class) 在整个系统中有且只有一个实例。
- 这个实例可以在整个系统被访问。
单例模式是游戏开发最最常用的设计模式之一,比如:各种资源管理类,核心数据类等等的实现大都需要这种“单例类”。
用 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
的直接子节点,而且会出现在其它节点的上方。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论