Cocos2d-x游戏引擎在直播类APP中的应用
2016-11-16叶远锋沈奇威
叶远锋, 沈奇威
(1 北京邮电大学网络与交换技术国家重点实验室,北京 100876; 2 东信北邮信息技术有限公司,北京 100191)
Cocos2d-x游戏引擎在直播类APP中的应用
叶远锋1,2, 沈奇威1,2
(1 北京邮电大学网络与交换技术国家重点实验室,北京 100876; 2 东信北邮信息技术有限公司,北京 100191)
本文提出了一种创新性的解决方案,将Cocos2d-x游戏引擎应用于直播类APP。作为一款游戏引擎,Cocos2d-x引擎具备功能强大的动画API,支持JavaScript脚本编程,而且使用JavaScript脚本编写的动画代码可以跨平台运行并可以实现热更新。
Cocos2d-x直播;动画;跨平台;热更新
近两年,视频直播行业迎来了爆发式的增长。以映客、花椒为代表的泛娱乐类直播APP迅速崛起,把直播带进了广大互联网用户的日常生活。数据显示,视频直播APP的人均单日启动次数接近12次,人均单日使用时长接近2 h。这预示着全民直播的时代已经悄然而至,同时,也意味着各家视频直播平台将会迎来激烈的竞争。在这种大环境下,如何通过技术手段提高生产效率、提升竞争优势显得尤为重要。
动画是泛娱乐类直播APP极为重要的一部分。泛娱乐类直播APP是面向年轻用户的且带有一定的社交成份,良好的产品体验和充满趣味的交互设计对于增加用户粘性十分重要,因此大部分的泛娱乐类直播APP都在产品里大量运用了动画特效,如点赞动画、用户进场动画、弹幕、礼物动画等。另一方面,动画经常需要根据产品运营策略的变化及时地做出调整或者更新,如不同节假日需要采用不同主题的动画、及时推出用户需求强烈的礼物动画等,因此,动画的及时更新对于产品运营来说也十分重要。
长久以来,APP的动画都采用原生方式开发,但是原生动画的实现方案存在着以下弊端。
(1) 动画代码无法跨平台运行,同样的动画,在不同的操作系统上都要实现一次。
(2) 动画无法热更新,用户必须更新APP才能看到新的动画效果。
(3) 动画调试不方便,每次修改动画都需要重新编译才能看到效果,开发效率低。
(4) 编写复杂的动画难度较高。
对于一般的对动画要求不高的APP来说,这些问题无足轻重;但是对于泛娱乐类直播APP来说,以上问题显得尤为突出。
Cocos2d-x作为一款游戏引擎,在动画处理方面具备得天独厚的优势。首先,它拥有一套功能强大的动画API,可以轻易写出效果炫酷的动画;其次,它支持JavaScript脚本编程,通过JavaScript脚本编写的动画代码可以跨平台运行,还可以实现热更新。另外,编写动画代码的时候可以在浏览器里面调试,十分有助于提高生产效率。因此,本文为泛娱乐类直播APP提出了一种创新性的动画解决方案,即将Cocos2d-x游戏引擎应用于直播APP,以解决现有原生动画解决方案遇到的问题。
1 相关技术
1.1Cocos2d-x
Cocos2d-x是MIT许可证下发布的开源游戏引擎,游戏开发快速、简易、功能强大。Cocos2d-x核心优势在于允许开发人员利用C++、Lua及JavaScript来进行跨平台部署,覆盖平台包括iOS、Android、Windows Phone、黑莓、Tizen等。
Cocos2d-x支持3种编程语言API:JavaScript API、Lua API和C++ API。在浏览器环境下,JavaScript API由Cocos2d-html5提供支持。Cocos2d-html5是Cocos2d-x的一个重要模块,是一个面向Web的游戏引擎,采用Canvas或者WebGL渲染,并完全兼容Html5规范,采用Cocos2d-x JavaScript API编写的游戏天然可运行在所有支持Html5规范的浏览器。
在原生平台环境下,JavaScript API由Cocos2d-JS Bindings模块、JavaScript虚拟机SpiderMonkey以及Cocos2d C++引擎提供支持。Cocos2d-JS Bindings模块,简称Cocos2d-x JSB,是一个介于C++代码和JavaScript代码之间的胶水层,用于对SpiderMonkey的功能进行扩展,使得SpiderMonkey可以支持Cocos2d-x C++引擎的数据结构和对象。通过SpiderMonkey,JavaScript API可以实现对底层Cocos2d-x C++引擎的调用。
1.2SpiderMonkey
SpiderMonkey是由C语言编写的JavaScript引擎,它支持JavaScript 1.4和ECMAScript-262规范。该引擎分析、编译和执行脚本,根据JavaScript数据类型和对象的需要进行内存分配及释放操作。利用该引擎可以让你的应用程序具有解释JavaScript脚本的能力。通过SpiderMonkey提供的JSAPI,第三方应用程序可以扩展SpiderMonkey的功能,使得第三方应用程序可以通过JavaScript代码调用底层的C++代码,反过来也可以在C++代码中调用JavaScript代码。
2 集成
2.1直播间架构
虽然从长远来看,Cocos2d-x引擎的引入可以提高生产效率、提升用户体验,但是也不可避免地在一定程度上增加系统的复杂性。为了降低系统的复杂性并且提升系统的可用性和可维护性,必须对直播间的架构进行良好的设计。
首先,需要对直播间的视觉层进行逻辑分层。自底向上分别是视频层、动画层以及交互层。视频层的展示优先级最低,其它视觉元素都可以覆盖在视频层之上,因此将视频层置于最底层;视频层之上是Cocos2d-x动画层,动画层专门负责动画特效的展示,如点赞动画、礼物动画、弹幕、用户进场动画等,动画层之内还可以根据具体情况进行更加细化的分层;最上层是交互层,负责展示交互元素以及捕获和处理用户操作。将动画层和交互层分离是一个很重要的设计,一方面是因为Cocos2d-x引擎并不擅长于复杂的UI布局,如用户信息弹框、礼物选择弹框等,另一方面是因为Cocos2d-x引擎不适合用来编写用户操作逻辑。
其次,在业务层面,将业务模块分为视频模块和动画模块。视频模块较为简单,它从直播流CDN获取编码视频流,然后将视频流解码并且绘制到视频层。动画模块由Cocos2d-x引擎、C++消息接口和动画消息队列组成。交互层会捕获用户的操作并将用户的操作封装成消息发送给服务端,服务端接收到用户操作消息之后,会根据消息类型作相应的处理,并在适当的时机通过长链接将动画消息推送给客户端,客户端将从服务端获取的动画消息存放进内存中的动画消息队列。而Cocos2d-x引擎则通过调度器定时调用C++消息接口从动画消息队列中获取动画消息并播放相应的动画特效。动画特效播放成功之后,Cocos2d-x引擎再调用C++消息接口将已播放的动画消息移出队列。
直播间的架构图如图1所示。
图1 直播间架构图
2.2热更新
APP的发布需要经历软件打包、应用商店审核等一系列步骤,这是一个相当繁琐而且耗时的过程,重新发布一次APP可能需要等上一周甚至半个月的时间。而泛娱乐类直播APP又十分强调动画特效的及时更新,这种传统的更新方式显然是不能满足需求的。因此,本文引入了Cocos2d-x引擎的热更新方案并加以改造以适用于直播APP的应用场景。
Cocos2d-x之所以能实现热更新,是因为它引入了对脚本语言的支持。脚本语言不需要编译,只需要运行时由解析器解析和执行。而脚本,作为一种普通的文本文件,可以很容易地被替换和更新。动画脚本的热更新流程如图2所示。
APP发布的时候,在安装包中会包含一个默认的配置文件project.manifest。文件的内容如图3所示。
(1) packageUrl:远程资源的下载根路径。
(2)remoteManifestUrl:远程配置文件(project. manifest)的路径,包含版本信息和所有资源信息。
图2 热更新流程图
(3)remoteVersionUrl:远程版本文件(version. manifest)的路径,用来判断服务端是否有新版本的资源;版本文件version.manifest是project.manifest的简化版,包含与project.manifest完全相同的前5项信息,这个文件是可选的。如果下载version.manifest文件失败,则自动下载完整的project.manifest文件,但是当project.manifest包含很多资源的时候,version. manifest将极大缩短版本比较的时间。
(4)version:配置文件对应的游戏版本。
(5)engineVersion:配置文件对应的游戏引擎版本。
(6) assets:所有资源信息。
(7) key:资源的相对路径(相对于packageUrl)。
(8) MD5:MD5值代表资源文件的指纹信息,如果本地文件的指纹信息和远程文件的指纹信息不一致,则更新本地文件。
(9) compressed:可选,如果值为true,文件被下载后会自动被解压。
(10)searchPaths:需要添加到Cocos2d引擎中的搜索路径列表。
图3 热更新配置文件
APP启动的时候,会根据本地project.manifest文件中的地址去下载服务端的version.manifest文件或者project.manifest文件并对其进行解析,获取其中的版本号字段值,即服务端动画脚本版本号。如果服务端动画脚本版本号与本地project.manifest文件中的版本号不一致,则进一步对比资源列表字段assets,然后下载其中新增的文件和指纹信息发生变化的文件到本地资源文件夹并覆盖旧的资源文件。资源文件更新结束后,对本地project.manifest文件进行更新。至此,Cocos2d-x引擎即可加载执行新的动画脚本。
利用Cocos2d-x的资源管理器AssetsManager提供的API可以轻松实现动画脚本的热更新,但是如果依赖于Cocos2d-x提供的API进行动画脚本的更新,那有可能会对动画的播放造成一定的延迟,因为Cocos2d-x引擎是在进入直播间之后才开始加载的。因此,为了避免对用户的使用体验造成坏的影响,必须将动画脚本的热更新逻辑从Cocos2d-x引擎中独立出来,在APP启动的时候就开始进行动画脚本的热更新。
2.3动画性能优化
通常,手机客户端的硬件资源有限,为了使APP运行更加流畅,需要进行对不同类型的动画进行相应的性能优化工作。
泛娱乐类直播APP的动画的种类通常有点赞动画、用户进场动画、弹幕动画、小礼物动画以及大礼物动画。前4种动画有一个共同点,即动画发生的频次高、动画占用内存少。对于这种类型的动画,如果每次都要重新创建和绘制动画节点,会极大地增加CPU和GPU的负担。而由于此类动画只需要极少的内存资源,因此可以在内存中缓存一部分动画节点以供再次使用,通过以空间换时间的方法来缓解CPU和GPU的压力,具体步骤如下。
(1)新的动画消息到来的时候,首先尝试从缓存中获取动画节点,如果失败,则创建新的节点。
(2) 使用当前的动画节点播放动画。
(3)动画播放完成,将当前动画节点放入缓冲池留待使用。
然而,对于大礼物动画则不能使用缓冲池策略,因为大礼物动画占用内存资源较大,而且大礼物动画发生的频次较低,将大礼物动画节点缓存起来不仅意义不大,还会造成内存压力过大。如图4所示,在不清除大礼物节点的情况下,连续播放两次大礼物动画会导致内存占用显著上升。
图4 优化前大礼物动画内存占用图
因此,对于大礼物动画节点,应该在需要播放大礼物动画的时候再创建,而且动画播放完成之后,应该立即将节点以及相关的资源移除。值得注意的是,Cocos2d-x引擎在清除精灵帧缓存的时候并不会清除与精灵帧相关联的图片纹理缓存,必须手动清除动画相关的图片纹理缓存。优化后的内存占用情况如图5所示。
图5 优化后大礼物动画内存占用图
2.4开发与调试
相比于原生动画开发,使用Cocos2d-x游戏引擎开发动画除了具有跨平台运行和在线热更新的好处以外,还能极大地提升开发效率。在原生动画的开发当中,编译源代码的过程是相当耗时的,每次修改完代码都要经历漫长的编译过程才能看到效果,这直接导致了动画开发效率的低下。Cocos2d-x动画的开发调试流程则要快捷得多,因为Cocos2d-x支持JavaScript编程,使用JavaScript编写的动画代码可以直接在浏览器运行,每次修改完代码之后,只需要刷新浏览器即可看到效果。如果借助于一些自动化工具,甚至可以做到编写完代码浏览器自动刷新。
此外,Cocos2d-x定义的JavaScript API专门为JavaScript程序员做过优化设计,接口简便易用,相比于Cocos2d-x C++ API而言,学习成本大大降低。
3 结论
针对当前直播类APP中原生动画开发方式的弊端,本文提出了基于Cocos2d-x的动画开发方案。使用Cocos2d-x引擎编写的代码具备跨平台运行、可在线热更新以及调试方便等优点,但是在现有APP中集成Cocos2d-x引擎,势必在一定程度上增加系统的复杂性。因此,必须做好架构的设计。Cocos2d-x引擎拥有强大的动画API,但是不适合用来做复杂的UI布局和编写业务逻辑,因此在架构上只让Cocos2d-x引擎负责动画的展现,UI布局和业务逻辑交给原生APP负责。为了使动画在APP上运行更加流畅,还需要对动画性能做一定的优化工作。对于频次高、内存占用少的动画,可以通过缓冲池策略缓解CPU压力;对于频次低、内存占用高的动画,则需要在动画结束之后将所有相关资源从内存中清除以避免内存占用持续升高。
[1]郑高强. Cocos2d-JS开发之旅:从HTML5到原生手机游戏[M].北京:电子工业出版社,2015.3.
[2]关东升. Cocos2d-x实战. JS卷:Cocos2d-JS开发[M]. 北京:清华大学出版社,2015.
[3]fusijie, pandamicro, wenhailin, zilongshanren. Cocos2d-x[EB/OL]. https://github.com/cocos2d/cocos2d-x. 2014.11-2016.04
[4]Ms2ger. JSAPI User Guide[EB/OL]. https://developer.mozilla.org/ en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide. 2015,11.
Cocos2d-x game engine's application in live APP
YE Yuan-feng1,2, SHEN Qi-wei1,2
(1 State Key Laboratory of Networking and Switching Technology, Beijing University of Posts and Telecommunications,Beijing 100876, China; 2 EBUPT Information Technology Co., Ltd., Beijing 100191, China)
This paper presents an innovative solution in which the Cocos2d-x game engine will be applied to live APPs. As a game engine, Cocos2d-x has a set of powerful animation API. Moreover, It supports scripting in JavaScript, which makes the animation code cross-platform and possible to achieve hot update.
Cocos2d-x live; animation; cross-platform; hot update
TN929.5
A
1008-5599(2016)10-0088-05
2016-08-26