主题

  1. 场景切换
  2. 场景间数据传递方式
  3. 小游戏全局背景音效

特别说明

CocosCreator微信小游戏开发系列文章,是我在逐步开发过程中,基于官方文档之上,记录一些重点内容,以及对官方文档中有些知识点的补充和分析。

正文

引擎同时只会运行一个场景,当切换新场景时,默认会将当前场景内所有节点和其他实例销毁。

1. 场景切换

假设从场景A切换到新场景B,中间会经历那些过程呢?

场景B预加载preloadScene -> 场景B的onLoad -> 场景B的onStart -> 跳转到场景B -> 场景A资源释放

//后台静默预加载新场景,cc.director.preloadScene("table", function () {    cc.log("Next scene preloaded");});//预加载没完成,也可以调用cc.director.loadScene("MyScene");
1.1 预加载阶段做了什么?
  • 会加载场景B中引用的静态资源,即属性检查器中引用的资源

  • 场景B中cc.resources和cc.assetManager加载的资源属于动态加载,不会在preloadScene阶段预加载

1.2 在onLoad和onStart方法中执行了过于耗时的操作,会导致页面黑屏或者跳转到场景B的速度很慢,造成无响应的假象。
1.3 场景A资源释放

场景A中引用的静态资源会被自动释放,但是动态加载的资源则需要开发者自己手动释放。

  • 对场景内单个资源的释放,可以使用release函数:
//cc.resources.load加载的单个资源释放,可以调用cc.resources.releasecc.resources.release("test assets/image", cc.SpriteFrame);cc.resources.release("test assets/anim");

//也可以使用 cc.assetManager.releaseAsset 来释放特定的 Asset 实例。cc.assetManager.releaseAsset(spriteFrame);
  • 单个资源出现被多个节点或者组件复用时,Asset Manager提供了一套基于引用计数的资源释放机制:
//每个组件加载资源时addRef()增加一个资源引用cc.resources.load('image', cc.SpriteFrame, (err, spriteFrame) => {  this.spriteFrame = spriteFrame;  spriteFrame.addRef();});

//每个组件destroy时,对应的调用decRef()减少一个资源引用this.spriteFrame.decRef();this.spriteFrame = null;

问题场景:

场景A在onLoad中动态加载了资源D,切到场景B中也动态加载了资源D,而根据引用计数的资源释放机制用法,在场景A中加载资源D时要addRef = 1,场景A销毁时要decRef = 0,资源D被释放了,但是这时候场景B中又动态加载了资源D要addRef + 1,就会出现场景B中资源D的isValid=false,导致资源无法显示了。而如果不decRef,场景B中的资源D会因为refCount不为0,而不会被释放。

结论:

从这个问题理解,引用计数的资源释放机制,应当是针对单个场景中多个组件引用相同资源D,才适合引用计数,在场景销毁时用来控制资源是否销毁的。

释放资源,要根据资源在各场景中的实际使用情形,结合release和引用计数来使用。

2. 场景间数据传递方式

2.1 常驻节点传递数据

场景A跳转场景B时,如何传递参数数据给场景B使用呢?

“cc.director.loadScene”方法没有携带参数启动场景的功能,CocosCreator是通过“常驻节点”进行场景资源管理和参数传递。“常驻节点”怎么理解呢?

当切换新场景时,默认会将当前场景内所有节点和其他实例销毁,而所谓“常驻节点”,是指在场景切换时不被自动销毁,常驻内存中的节点组件。那这个常驻节点应当建在哪里呢?

首先CocosCreator是推荐使用Canvas节点作为渲染根节点的,并且微信小游戏强制要求渲染根节点必须是Canvas。常驻节点创建的位置是和Canvas节点平级,即不能作为Canvas节点的子节点,而是应当在场景的根节点下,如下图所示。分析原因可能有两种:

  • 如果常驻节点在Canvas内,因为节点不会被销毁,会导致Canvas节点也不能销毁,多切换几个场景,内存可能就已经满了;
  • 从节点功能上看,常驻节点只是空节点,而Canvas属于渲染节点,它的子节点都是用于渲染UI使用,所以也不应该放到Canvas节点下。

常驻节点的创建位置

将StartData节点设置成常驻节点:

  //添加dataNode为常驻节点  cc.game.addPersistRootNode(this.dataNode);  //设置dataNode要传递的数据  this.dataNode.data = {data : "123"}

在新场景中获取传递的数据:

  onLoad() {      //从上一个场景的常驻节点上获取当前场景需要使用的参数      var startData = cc.director.getScene().getChildByName('StartData');      if (startData) {          this.data = startData.data;          // cc.log('页面传递的参数,从常驻节点中获得data:', this.data);

          //取消一个节点的常驻属性          cc.game.removePersistRootNode(startData);      }      ...  },

注意: cc.game.removePersistRootNode 并不会立即销毁指定节点,只是将节点还原为可在场景切换时销毁的节点。

2.2 使用全局变量

定义全局变量 window.Global:

  window.Global = {      data: null  };

由于所有脚本都强制声明为 "use strict",因此定义全局变量时的 window. 不可省略。接着在需要使用的地方可直接初始化 Global 并访问它:

  // home.js

  cc.Class({      extends: cc.Component,

      onLoad: function () {          Global.data = { data : "123"};      },

      // start 会在 onLoad 之后执行,所以这时 Global 已经初始化过了      start: function () {          this.txtLabel.string = Global.data.data;      }  });

注意:

  • 不推荐滥用全局变量;
  • 访问全局变量时,需确保全局变量已初始化和赋值,否则将会抛出异常;
  • 定义全局变量时,不能和系统已有的全局变量重名;
  • 你需要小心确保全局变量使用之前都已初始化和赋值。

3. 小游戏全局背景音效

全局背景音乐的播放,看完上面的内容应当知道怎么实现了吧,如果还不知道做的,你可以再仔细往上看一看。

  1. 创建常驻节点AudioNode

  2. 编写AudioManager.js音乐播放脚本

cc.Class({  extends: cc.Component,

  properties: {      bgMusic: {          url: cc.AudioClip,          default: null      },  },

  onLoad() {      cc.game.addPersistRootNode(this.node);

      if (!this.bgMusic) {            cc.assetManager.loadRemote('https://www.test.com/game_bgm.mp3', function(err, audio) {                if (err) {                    console.log("加载失败:" + err);                }

                if (audio instanceof cc.AudioClip) {                    this.bgMusic = audio;                    //停止再开启背景音乐                    this.playBgMusic();                }            }.bind(this));        } else {            this.playBgMusic();        }  },

  playBgMusic() {      if (this.bgMusic) {          this.bgMusicChannel = cc.audioEngine.play(this.bgMusic, true, 0.3)      }  },

  stopBgMusic: function () {      if (this.bgMusicChannel !== undefined) {          cc.audioEngine.stop(this.bgMusicChannel);          this.bgMusicChannel = undefined;      }  },

});
  1. 把AudioManager.js脚本挂载到AudioNode节点上

挂载AudioManager.js

如果在属性面板没有设置bgMusic播放的音频资源,则动态播放默认音频资源。

结尾

既然您看到这了,说明文章对你还有用,帮忙点个赞再走吧,谢谢!

自己动手写,分解项目中的各个模块需求,通过查文档和搜索Cocos社区,解决碰到的问题,最终在微信上线了下面这款微信小游戏《成语锦衣卫》,欢迎大家扫码体验,并作为参考项目模版,开发出属于自己的小游戏

预告

下一节和朋友们说一说:微信登录功能的实现,CocosCreator第三方服务腾讯TCB云开发踩坑和微信云开发

动态加载子节点_微信小游戏开发之场景切换和常驻节点传递数据相关推荐

  1. 微信小游戏开发学习记录2

    接上一篇:微信小游戏开发学习记录_寂静流年韶华舞的博客-CSDN博客_微信小游戏开发学习 目录 一.UI系统 1.基础渲染组件-精灵组件 (1)操作: (2)Sprite 属性 (3)渲染模式 2.L ...

  2. 微信小游戏开发(9)- 分包加载

    随着小游戏的玩法越来越丰富,开发者对于扩大包大小的需求越来越强烈,所以微信推出了小游戏分包加载这一个功能. 所谓的分包加载,即把游戏内容按照一定的规则拆分成几个包,在首次启动时先下载必要的包,这个必要 ...

  3. 白鹭引擎拉伸高度_答疑汇总|白鹭引擎架构师开源中国社区分享微信小游戏开发技巧...

    原标题:答疑汇总|白鹭引擎架构师开源中国社区分享微信小游戏开发技巧 1月31日-2月6日,开源中国社区邀请白鹭引擎首席架构师王泽以"微信小游戏开发技巧分享"为主题,为广大开发者带来 ...

  4. 《欢乐坦克大战》微信小游戏开发总结

    <欢乐坦克大战>微信小游戏开发总结 <欢乐坦克大战>微信小游戏开发总结 前言 <欢乐坦克大战>是一款支持3V3实时对战并首批参与上线的微信小游戏中的作品.因为该游戏 ...

  5. 白鹭引擎正式支持微信小游戏开发

    12月28日微信迎来更新,正式上线小游戏,并开放了小游戏开发文档和开发者工具.在微信发布新版本后,白鹭引擎立即添加了对于微信小游戏开发的支持,开发者只需要使用白鹭引擎的最新版本,通过使用白鹭引擎完整工 ...

  6. 搭建微信小游戏开发环境总结

    这篇文章主要解决以下问题 1.一键申请泛域名证书并到期自动更新 2.Nginx配置https 3.本地资源映射到外网 4.介绍CocosCreator构建发布微信小游戏时远程服务器地址如何配置 文章目 ...

  7. 微信小游戏开发实战教程14-闯关模式的实现

    这是微信小游戏开发实战系列的第14篇. 本文主要内容是介绍精致1010闯关模式的设计和实现思路. 如果你没有任何的游戏开发经验,欢迎阅读我的"人人都能做游戏"系列教程,它会手把手的 ...

  8. 微信小游戏开发教程-游戏实现3

    微信小游戏开发教程-游戏实现3 对象池 由于游戏过程中会创建很多临时对象,这些对象很快又不再使用,垃圾回收器也能帮我们主动回收这部分垃圾,但是回收时间不可控制,同时增大了创建对象的开销,所以我们使用对 ...

  9. 微信小游戏开发教程-游戏实现2

    微信小游戏开发教程-游戏实现2 绘制地面 类似于绘制背景,读者自行完成代码.src/runtime/land.js 简易View系统 坐标布局对于复杂的页面来说维护相当困难,因此这里我们引入布局的概念 ...

最新文章

  1. Python find方法与rfind方法的使用
  2. oracle 无效对象,Oracle编译用户无效对象
  3. 【tf.keras】TensorFlow 1.x 到 2.0 的 API 变化
  4. 源码编译安装mysql,DDL数据定义语言的使用。
  5. Java实现几种常见排序方法
  6. 强化学习-动态规划_强化学习-第5部分
  7. (剑指Offer)面试题5:从尾到头打印链表
  8. java 几个线程池的理解
  9. 26. 左旋转字符串
  10. 實驗項目wordcount
  11. MySQL优化之——触发器
  12. java快速排列马桶,马桶Java :6.高性能MySQL语句(二)
  13. python pyquery不规则数据的抓取_11. 数据提取-PyQuery
  14. SpringBoot1.5.9集成Activiti6
  15. 《计算机系统:系统架构与操作系统的高度集成》——1.5 计算机硬件的演化...
  16. atitit 碎片化学习.docx attilax 总结
  17. 小甲鱼python笔记_小甲鱼Python笔记(类)
  18. 二级建造师学python有用_二级建造师
  19. APEX光学分析设计软件
  20. android 天气动态壁纸,动态桌面壁纸 安卓“墨迹天气”新版评测

热门文章

  1. TLU-Net:表面缺陷自动检测的深度学习方法
  2. AC3 bit allocation
  3. oracle12之 多租户容器数据库架构
  4. SAX解析XML文档——(二)
  5. Action Golf 四个魔法球实战训练系列_huatuo_新浪博客
  6. SVN之版本控制系统
  7. ADMT3.2域迁移之Server2003至Server2012系列(八)生成密钥文件及安装密码迁移工具...
  8. 数据挖掘视频教程下载
  9. 心情不能平静,慢慢的调节
  10. icop java,java基于spring注解AOP的异常处理的方法