使用常驻节点
使用全局变量
使用本地存储
引擎同时只会运行一个场景,当切换场景时,默认会将场景内所有节点和其他实例销毁(本句来自Cocos Creator文档)。
在这一节教程中,我们将讨论下如何在场景切换时保留下必要的节点信息。 其实Cocos Creator文档已经给我们提供了三种方法:
使用常驻节点 使用全局变量 使用模块访问笔者在这一节中会再加一个:使用本地存储。现在我们通过实例来进行演示。
Cocos Creator版本:2.2.2
后台回复"保留节点信息",获取该项目完整文件:
使用常驻节点我们知道在切换场景后,背景音乐会从头开始播放。那如果要让音乐继续播放的话,我们就可以利用常驻节点来实现。在这一小点中笔者将通过一个背景音乐播放例子来演示如何使用常驻节点。
首先笔者在资源管理器中创建了两个Scene:
在常驻节点场景中我们实现相关逻辑。 跳转到测试结果场景后,我们再次跳转回常驻节点,检查音乐是否停下。常驻节点场景内容:
Bg Music是一个空节点,上面挂有Music.js脚本。注意一定要放在Canvas节点外。如果放在Canvas节点里面,那么从其他场景跳回来时,会重新生成一个Bg Music,而之前的Bg Music又没有消失,所以会导致有多个背景音乐同时在播放的情况。 New Button就是一个按钮节点,用于场景切换。Music.js内容如下:
// Music.js
cc.Class({
extends: cc.Component,
properties: {
bgAudio: {
default: null,
type: cc.AudioClip
}
},
// LIFE-CYCLE CALLBACKS:
onLoad () {
cc.game.addPersistRootNode(this.node); // 将该节点添加为常驻节点
cc.audioEngine.playEffect(this.bgAudio); // 播放背景音乐
},
});
这里最重要的代码就是 cc.game.addPersistRootNode(this.node); 这一行代码可以让当前脚本所在节点变为常驻节点,也就是说场景切换时,该节点不会被销毁,那么背景音乐自然也就会一直播放了。
再创建一个Button.js,挂到New Button节点上,内容如下:
// Button.js
cc.Class({
extends: cc.Component,
changeScene () {
cc.director.loadScene('测试结果'); // 切换场景
}
});
changeScene就是按钮的点击事件函数。注意不能在常驻节点中编写这类函数,否则按钮会不起作用。
测试结果场景内容:
非常简单,就一个Label和按钮节点,按钮用于跳回常驻节点场景。Canvas节点上挂有Test.js脚本,内容如下:
// Test.js
cc.Class({
extends: cc.Component,
properties: {
},
persisitentNodeScene () {
cc.director.loadScene('常驻节点'); // 回到常驻节点场景
}
});
现在回到常驻节点场景,然后运行下,就会发现背景音乐是继续播放的。
注:用于演示的背景音乐素材是从爱给网上下载的。
使用全局变量
我们通过在不同场景间传递一个字符串来演示下如何使用全局变量来保存节点信息。
首先创建一个新的场景,命名为全局变量:
全局变量场景内容如下:
New Label节点上的文本内容就是我们要在场景间传递的信息。
New Button节点用于跳转到测试结果场景。
接着创建两个脚本文件:Global.js和NewScript.js,内容如下:
// Global.js
window.Global = {
labelStr: null
}
// NewScript.js
cc.Class({
extends: cc.Component,
properties: {
label: cc.Label,
},
// LIFE-CYCLE CALLBACKS:
onLoad () {
Global.labelStr = this.label.string;
},
changeScene () {
cc.director.loadScene('测试结果'); // 切换场景
}
});
很简单,就是先在Global.js中创建一个全局变量,然后在NewScript.js中将文本内容保存到该变量中。
测试场景内容如下:
我们现在往Test.js脚本中添加一些内容:
// Test.js
cc.Class({
extends: cc.Component,
properties: {
label: cc.Label
},
onLoad () {
if (Global.labelStr) { // 增加代码
this.label.string = Global.labelStr;
}
},
persisitentNodeScene () {
cc.director.loadScene('常驻节点'); // 回到常驻节点场景
}
});
如果Global全局变量的labelStr键有值的话,那我们就将测试结果场景中的文本标签设为labelStr的值。
现在回到全局变量场景,运行然后跳转到测试场景,就会发现文本内容被传过来了:
官方还给了通过模块访问的例子,大家可以去看下,笔者这里就不再用实例进行演示。
使用本地存储
其实用本地存储来保存信息跟用全局变量来保存的道理是类似的。不过前者的主要作用不是在转场时保存节点信息,而是用于实现存档功能。如果你游戏的某些数据不仅需要在转场时进行保存,而且在下次启动时还需要再次读取。那么笔者建议使用本地存储而不是全局变量。
比方说《守护鱼干》这款微信小游戏,游戏需要记录玩家采集的小草、石头和金币数,因为这些材料可以拿来在商店中换取一些猫咪玩具。所以在跳转到商店场景中时,我们需要保存在主场景中已经拥有的小草、石头和金币数。
不仅如此,玩家下次启动时,这些材料的数量也要跟上次退出游戏时的材料数一样。
现在来看下如何使用。
首先创建一个本地存储场景,内容如下:
New Label节点的文本内容就是我们要保存到本地的信息。
New Button节点用于跳转到测试结果场景。
现在新建一个LocalStorage.js脚本,挂到Canvas节点上,内容如下:
// LocalStorage.js
cc.Class({
extends: cc.Component,
properties: {
label: cc.Label
},
// LIFE-CYCLE CALLBACKS:
onLoad () {
let name = this.label.string;
cc.sys.localStorage.setItem('name', name);
},
changeScene () {
cc.director.loadScene('测试结果'); // 切换场景
}
});
将文本内容直接存储到本地中,键名为name,值为this.label.string。
测试场景内容如下:
我们在层级管理器中新增一个Label节点:
该节点将用于显示之前保存到本地存储中的内容。Test.js修改如下:
// Test.js
cc.Class({
extends: cc.Component,
properties: {
label: cc.Label,
label2: cc.Label
},
onLoad () {
if (Global.labelStr) {
this.label.string = Global.labelStr;
}
let name = cc.sys.localStorage.getItem('name'); // 增加代码
this.label2.string = name;
},
persisitentNodeScene () {
cc.director.loadScene('常驻节点'); // 回到常驻节点场景
}
});
就是用本地存储中读取name键的值,然后显示到label2上。
现在回到本地存储场景,运行并跳转到测试结果场景,就会发现传值成功了:
注:必须先运行本地存储场景,否则本地存储中会没有name键。
好,那本节教程就到这,希望大家有所收获~
作者:la_vie_est_belle