3.4 多场景切换
到目前为止已经实现了自定义的场景,并能从游戏加载进入后直接进入所创建的场景中。大家知道,在游戏里一个一个的场景是需要进行切换的,在Cocos中场景又如何切换呢?
在3.1节中说到了Cocos中的四大元素——导演、场景、精灵和图层。其中,整个游戏的核心就是导演,在Cocos中导演用单例类cc.Director来表示,在使用cc.Director的时候可以通过cc.director使用,cc.director实际上也是调用了cc.Director的_getInstance()方法。一般使用导演来进行场景之间的切换,构建一个游戏是需要多个场景的,而Director类提供了对这些场景的管理。本节的所有代码均在MultiSceneDemo项目中。
3.4.1 导演的作用
通过Cocos的官网可以找到对导演和场景的解释,地址为“http://www.cocos.com/docs/native/v3/basic-concepts/zh.html”,从官方文档中可以看到导演有以下几个作用。
- 环境设定:游戏帧率设置、动作管理器、事件管理器,OpenGL ES等初始加载,世界坐标和GL坐标的切换。
- 游戏主循环控制:与动画原理相同,游戏也是由Director一帧一帧地渲染的,而整个渲染的过程在Director主循环体中,因此整个游戏的开始、暂停、恢复、结束等都由Director管理。
- 场景管理:Director最重要的作用就是对场景的管理了,包括场景的创建、销毁、切换等操作。
3.4.2 Director的常用方法
通过查看CCDirector.js的源码可以看到Director的常用方法有以下几个。
可以看到有pop和push方法,有程序基础的读者应该知道,在数据结构中有一种数据结构叫栈,而Director对场景的管理就是采用栈的结构来实现的,这种数据结构简单来说就是先进后出。
栈的结构可以比喻为一个羽毛球筒,我们往里放羽毛球的时候最先放进去的一定在最下面,最后放进去的一定在最上面,当要取羽毛球的时候一定是从最上面开始取的,也就是说最先取出的羽毛球一定是最后放进去的。
导演对于场景的管理也是这样的结构,当导演push一个场景时会将当前的场景放入场景栈中,当需要push新场景的时候导演会将新的场景再放入场景栈中,重叠在第一个场景的上面,而第一个场景依然是存在的,当导演pop场景时会先取出最上面的场景,再做pop操作时会依次取出下面的场景。通常情况下用push和pop管理场景会比较麻烦,因为有时很容易将哪些场景初始化了,哪些没有,哪些是首次出现等情况搞混,而导演提供了一个runScene方法解决了管理混乱的问题,runScene方法的源码如下。
从源码部分可以看出,导演判断当前没有场景运行时直接调用pushScene,如果当前有运行的场景,则直接替换为当前场景。
在实际开发中可根据实际需要来选择管理场景的方法,例如,在对场景的数据等无须保留的情况下,可以直接使用runScene来切换场景;如果对场景中数据的加载先后及时间比较重视,可以选用pop/push手动管理场景,一切均以实际开发的需求而定。
3.4.3 场景切换Demo
这里通过一个小Demo熟悉最常用的runScene方法来切换场景,在游戏中一般都会有开始场景、游戏场景和帮助场景等,下面以这3种最基本的场景切换为例加以介绍。
首先创建首次进入的场景HelloWorldScene,代码如下。
如代码所示,创建了两个按钮,单击即可跳转场景,创建了一个单击添加文本控件的菜单项来测试调用runScene时场景是否销毁。单击添加几个文本控件,看到的效果如图3-7所示。
图3-7 开始场景
当单击“开始”按钮时会跳转游戏场景,游戏场景的代码如下。
在游戏场景中简单显示“游戏场景”几个字,并且添加一个“返回主界面”的按钮,单击即可切换回开始场景。其运行如图3-8所示。
当单击“帮助”按钮时会进入帮助场景,帮助场景的代码如下。
图3-8 游戏场景
如代码所示,在帮助场景中只简单地显示“帮助场景”几个文字。其运行如图3-9所示。
当从游戏场景返回开始场景时会发现那几个添加的文本已经不见了,说明场景重新进行了加载,可以说明runScene方法在替换当前场景时会销毁之前的场景。
如上就是一个小小的模拟游戏运行中的各个场景切换的例子,runScene只是切换场景的一个方法,Director还有很多与场景相关的API,建议大家多去官网了解,更深入、更全面地了解Director类。
图3-9 帮助场景