葉遠(yuǎn)鋒, 沈奇威
(1 北京郵電大學(xué)網(wǎng)絡(luò)與交換技術(shù)國家重點(diǎn)實(shí)驗(yàn)室,北京 100876; 2 東信北郵信息技術(shù)有限公司,北京 100191)
Cocos2d-x游戲引擎在直播類APP中的應(yīng)用
葉遠(yuǎn)鋒1,2, 沈奇威1,2
(1 北京郵電大學(xué)網(wǎng)絡(luò)與交換技術(shù)國家重點(diǎn)實(shí)驗(yàn)室,北京 100876; 2 東信北郵信息技術(shù)有限公司,北京 100191)
本文提出了一種創(chuàng)新性的解決方案,將Cocos2d-x游戲引擎應(yīng)用于直播類APP。作為一款游戲引擎,Cocos2d-x引擎具備功能強(qiáng)大的動(dòng)畫API,支持JavaScript腳本編程,而且使用JavaScript腳本編寫的動(dòng)畫代碼可以跨平臺(tái)運(yùn)行并可以實(shí)現(xiàn)熱更新。
Cocos2d-x直播;動(dòng)畫;跨平臺(tái);熱更新
近兩年,視頻直播行業(yè)迎來了爆發(fā)式的增長。以映客、花椒為代表的泛娛樂類直播APP迅速崛起,把直播帶進(jìn)了廣大互聯(lián)網(wǎng)用戶的日常生活。數(shù)據(jù)顯示,視頻直播APP的人均單日啟動(dòng)次數(shù)接近12次,人均單日使用時(shí)長接近2 h。這預(yù)示著全民直播的時(shí)代已經(jīng)悄然而至,同時(shí),也意味著各家視頻直播平臺(tái)將會(huì)迎來激烈的競爭。在這種大環(huán)境下,如何通過技術(shù)手段提高生產(chǎn)效率、提升競爭優(yōu)勢顯得尤為重要。
動(dòng)畫是泛娛樂類直播APP極為重要的一部分。泛娛樂類直播APP是面向年輕用戶的且?guī)в幸欢ǖ纳缃怀煞?,良好的產(chǎn)品體驗(yàn)和充滿趣味的交互設(shè)計(jì)對于增加用戶粘性十分重要,因此大部分的泛娛樂類直播APP都在產(chǎn)品里大量運(yùn)用了動(dòng)畫特效,如點(diǎn)贊動(dòng)畫、用戶進(jìn)場動(dòng)畫、彈幕、禮物動(dòng)畫等。另一方面,動(dòng)畫經(jīng)常需要根據(jù)產(chǎn)品運(yùn)營策略的變化及時(shí)地做出調(diào)整或者更新,如不同節(jié)假日需要采用不同主題的動(dòng)畫、及時(shí)推出用戶需求強(qiáng)烈的禮物動(dòng)畫等,因此,動(dòng)畫的及時(shí)更新對于產(chǎn)品運(yùn)營來說也十分重要。
長久以來,APP的動(dòng)畫都采用原生方式開發(fā),但是原生動(dòng)畫的實(shí)現(xiàn)方案存在著以下弊端。
(1) 動(dòng)畫代碼無法跨平臺(tái)運(yùn)行,同樣的動(dòng)畫,在不同的操作系統(tǒng)上都要實(shí)現(xiàn)一次。
(2) 動(dòng)畫無法熱更新,用戶必須更新APP才能看到新的動(dòng)畫效果。
(3) 動(dòng)畫調(diào)試不方便,每次修改動(dòng)畫都需要重新編譯才能看到效果,開發(fā)效率低。
(4) 編寫復(fù)雜的動(dòng)畫難度較高。
對于一般的對動(dòng)畫要求不高的APP來說,這些問題無足輕重;但是對于泛娛樂類直播APP來說,以上問題顯得尤為突出。
Cocos2d-x作為一款游戲引擎,在動(dòng)畫處理方面具備得天獨(dú)厚的優(yōu)勢。首先,它擁有一套功能強(qiáng)大的動(dòng)畫API,可以輕易寫出效果炫酷的動(dòng)畫;其次,它支持JavaScript腳本編程,通過JavaScript腳本編寫的動(dòng)畫代碼可以跨平臺(tái)運(yùn)行,還可以實(shí)現(xiàn)熱更新。另外,編寫動(dòng)畫代碼的時(shí)候可以在瀏覽器里面調(diào)試,十分有助于提高生產(chǎn)效率。因此,本文為泛娛樂類直播APP提出了一種創(chuàng)新性的動(dòng)畫解決方案,即將Cocos2d-x游戲引擎應(yīng)用于直播APP,以解決現(xiàn)有原生動(dòng)畫解決方案遇到的問題。
1.1Cocos2d-x
Cocos2d-x是MIT許可證下發(fā)布的開源游戲引擎,游戲開發(fā)快速、簡易、功能強(qiáng)大。Cocos2d-x核心優(yōu)勢在于允許開發(fā)人員利用C++、Lua及JavaScript來進(jìn)行跨平臺(tái)部署,覆蓋平臺(tái)包括iOS、Android、Windows Phone、黑莓、Tizen等。
Cocos2d-x支持3種編程語言API:JavaScript API、Lua API和C++ API。在瀏覽器環(huán)境下,JavaScript API由Cocos2d-html5提供支持。Cocos2d-html5是Cocos2d-x的一個(gè)重要模塊,是一個(gè)面向Web的游戲引擎,采用Canvas或者WebGL渲染,并完全兼容Html5規(guī)范,采用Cocos2d-x JavaScript API編寫的游戲天然可運(yùn)行在所有支持Html5規(guī)范的瀏覽器。
在原生平臺(tái)環(huán)境下,JavaScript API由Cocos2d-JS Bindings模塊、JavaScript虛擬機(jī)SpiderMonkey以及Cocos2d C++引擎提供支持。Cocos2d-JS Bindings模塊,簡稱Cocos2d-x JSB,是一個(gè)介于C++代碼和JavaScript代碼之間的膠水層,用于對SpiderMonkey的功能進(jìn)行擴(kuò)展,使得SpiderMonkey可以支持Cocos2d-x C++引擎的數(shù)據(jù)結(jié)構(gòu)和對象。通過SpiderMonkey,JavaScript API可以實(shí)現(xiàn)對底層Cocos2d-x C++引擎的調(diào)用。
1.2SpiderMonkey
SpiderMonkey是由C語言編寫的JavaScript引擎,它支持JavaScript 1.4和ECMAScript-262規(guī)范。該引擎分析、編譯和執(zhí)行腳本,根據(jù)JavaScript數(shù)據(jù)類型和對象的需要進(jìn)行內(nèi)存分配及釋放操作。利用該引擎可以讓你的應(yīng)用程序具有解釋JavaScript腳本的能力。通過SpiderMonkey提供的JSAPI,第三方應(yīng)用程序可以擴(kuò)展SpiderMonkey的功能,使得第三方應(yīng)用程序可以通過JavaScript代碼調(diào)用底層的C++代碼,反過來也可以在C++代碼中調(diào)用JavaScript代碼。
2.1直播間架構(gòu)
雖然從長遠(yuǎn)來看,Cocos2d-x引擎的引入可以提高生產(chǎn)效率、提升用戶體驗(yàn),但是也不可避免地在一定程度上增加系統(tǒng)的復(fù)雜性。為了降低系統(tǒng)的復(fù)雜性并且提升系統(tǒng)的可用性和可維護(hù)性,必須對直播間的架構(gòu)進(jìn)行良好的設(shè)計(jì)。
首先,需要對直播間的視覺層進(jìn)行邏輯分層。自底向上分別是視頻層、動(dòng)畫層以及交互層。視頻層的展示優(yōu)先級最低,其它視覺元素都可以覆蓋在視頻層之上,因此將視頻層置于最底層;視頻層之上是Cocos2d-x動(dòng)畫層,動(dòng)畫層專門負(fù)責(zé)動(dòng)畫特效的展示,如點(diǎn)贊動(dòng)畫、禮物動(dòng)畫、彈幕、用戶進(jìn)場動(dòng)畫等,動(dòng)畫層之內(nèi)還可以根據(jù)具體情況進(jìn)行更加細(xì)化的分層;最上層是交互層,負(fù)責(zé)展示交互元素以及捕獲和處理用戶操作。將動(dòng)畫層和交互層分離是一個(gè)很重要的設(shè)計(jì),一方面是因?yàn)镃ocos2d-x引擎并不擅長于復(fù)雜的UI布局,如用戶信息彈框、禮物選擇彈框等,另一方面是因?yàn)镃ocos2d-x引擎不適合用來編寫用戶操作邏輯。
其次,在業(yè)務(wù)層面,將業(yè)務(wù)模塊分為視頻模塊和動(dòng)畫模塊。視頻模塊較為簡單,它從直播流CDN獲取編碼視頻流,然后將視頻流解碼并且繪制到視頻層。動(dòng)畫模塊由Cocos2d-x引擎、C++消息接口和動(dòng)畫消息隊(duì)列組成。交互層會(huì)捕獲用戶的操作并將用戶的操作封裝成消息發(fā)送給服務(wù)端,服務(wù)端接收到用戶操作消息之后,會(huì)根據(jù)消息類型作相應(yīng)的處理,并在適當(dāng)?shù)臅r(shí)機(jī)通過長鏈接將動(dòng)畫消息推送給客戶端,客戶端將從服務(wù)端獲取的動(dòng)畫消息存放進(jìn)內(nèi)存中的動(dòng)畫消息隊(duì)列。而Cocos2d-x引擎則通過調(diào)度器定時(shí)調(diào)用C++消息接口從動(dòng)畫消息隊(duì)列中獲取動(dòng)畫消息并播放相應(yīng)的動(dòng)畫特效。動(dòng)畫特效播放成功之后,Cocos2d-x引擎再調(diào)用C++消息接口將已播放的動(dòng)畫消息移出隊(duì)列。
直播間的架構(gòu)圖如圖1所示。
圖1 直播間架構(gòu)圖
2.2熱更新
APP的發(fā)布需要經(jīng)歷軟件打包、應(yīng)用商店審核等一系列步驟,這是一個(gè)相當(dāng)繁瑣而且耗時(shí)的過程,重新發(fā)布一次APP可能需要等上一周甚至半個(gè)月的時(shí)間。而泛娛樂類直播APP又十分強(qiáng)調(diào)動(dòng)畫特效的及時(shí)更新,這種傳統(tǒng)的更新方式顯然是不能滿足需求的。因此,本文引入了Cocos2d-x引擎的熱更新方案并加以改造以適用于直播APP的應(yīng)用場景。
Cocos2d-x之所以能實(shí)現(xiàn)熱更新,是因?yàn)樗肓藢δ_本語言的支持。腳本語言不需要編譯,只需要運(yùn)行時(shí)由解析器解析和執(zhí)行。而腳本,作為一種普通的文本文件,可以很容易地被替換和更新。動(dòng)畫腳本的熱更新流程如圖2所示。
APP發(fā)布的時(shí)候,在安裝包中會(huì)包含一個(gè)默認(rèn)的配置文件project.manifest。文件的內(nèi)容如圖3所示。
(1) packageUrl:遠(yuǎn)程資源的下載根路徑。
(2)remoteManifestUrl:遠(yuǎn)程配置文件(project. manifest)的路徑,包含版本信息和所有資源信息。
圖2 熱更新流程圖
(3)remoteVersionUrl:遠(yuǎn)程版本文件(version. manifest)的路徑,用來判斷服務(wù)端是否有新版本的資源;版本文件version.manifest是project.manifest的簡化版,包含與project.manifest完全相同的前5項(xiàng)信息,這個(gè)文件是可選的。如果下載version.manifest文件失敗,則自動(dòng)下載完整的project.manifest文件,但是當(dāng)project.manifest包含很多資源的時(shí)候,version. manifest將極大縮短版本比較的時(shí)間。
(4)version:配置文件對應(yīng)的游戲版本。
(5)engineVersion:配置文件對應(yīng)的游戲引擎版本。
(6) assets:所有資源信息。
(7) key:資源的相對路徑(相對于packageUrl)。
(8) MD5:MD5值代表資源文件的指紋信息,如果本地文件的指紋信息和遠(yuǎn)程文件的指紋信息不一致,則更新本地文件。
(9) compressed:可選,如果值為true,文件被下載后會(huì)自動(dòng)被解壓。
(10)searchPaths:需要添加到Cocos2d引擎中的搜索路徑列表。
圖3 熱更新配置文件
APP啟動(dòng)的時(shí)候,會(huì)根據(jù)本地project.manifest文件中的地址去下載服務(wù)端的version.manifest文件或者project.manifest文件并對其進(jìn)行解析,獲取其中的版本號字段值,即服務(wù)端動(dòng)畫腳本版本號。如果服務(wù)端動(dòng)畫腳本版本號與本地project.manifest文件中的版本號不一致,則進(jìn)一步對比資源列表字段assets,然后下載其中新增的文件和指紋信息發(fā)生變化的文件到本地資源文件夾并覆蓋舊的資源文件。資源文件更新結(jié)束后,對本地project.manifest文件進(jìn)行更新。至此,Cocos2d-x引擎即可加載執(zhí)行新的動(dòng)畫腳本。
利用Cocos2d-x的資源管理器AssetsManager提供的API可以輕松實(shí)現(xiàn)動(dòng)畫腳本的熱更新,但是如果依賴于Cocos2d-x提供的API進(jìn)行動(dòng)畫腳本的更新,那有可能會(huì)對動(dòng)畫的播放造成一定的延遲,因?yàn)镃ocos2d-x引擎是在進(jìn)入直播間之后才開始加載的。因此,為了避免對用戶的使用體驗(yàn)造成壞的影響,必須將動(dòng)畫腳本的熱更新邏輯從Cocos2d-x引擎中獨(dú)立出來,在APP啟動(dòng)的時(shí)候就開始進(jìn)行動(dòng)畫腳本的熱更新。
2.3動(dòng)畫性能優(yōu)化
通常,手機(jī)客戶端的硬件資源有限,為了使APP運(yùn)行更加流暢,需要進(jìn)行對不同類型的動(dòng)畫進(jìn)行相應(yīng)的性能優(yōu)化工作。
泛娛樂類直播APP的動(dòng)畫的種類通常有點(diǎn)贊動(dòng)畫、用戶進(jìn)場動(dòng)畫、彈幕動(dòng)畫、小禮物動(dòng)畫以及大禮物動(dòng)畫。前4種動(dòng)畫有一個(gè)共同點(diǎn),即動(dòng)畫發(fā)生的頻次高、動(dòng)畫占用內(nèi)存少。對于這種類型的動(dòng)畫,如果每次都要重新創(chuàng)建和繪制動(dòng)畫節(jié)點(diǎn),會(huì)極大地增加CPU和GPU的負(fù)擔(dān)。而由于此類動(dòng)畫只需要極少的內(nèi)存資源,因此可以在內(nèi)存中緩存一部分動(dòng)畫節(jié)點(diǎn)以供再次使用,通過以空間換時(shí)間的方法來緩解CPU和GPU的壓力,具體步驟如下。
(1)新的動(dòng)畫消息到來的時(shí)候,首先嘗試從緩存中獲取動(dòng)畫節(jié)點(diǎn),如果失敗,則創(chuàng)建新的節(jié)點(diǎn)。
(2) 使用當(dāng)前的動(dòng)畫節(jié)點(diǎn)播放動(dòng)畫。
(3)動(dòng)畫播放完成,將當(dāng)前動(dòng)畫節(jié)點(diǎn)放入緩沖池留待使用。
然而,對于大禮物動(dòng)畫則不能使用緩沖池策略,因?yàn)榇蠖Y物動(dòng)畫占用內(nèi)存資源較大,而且大禮物動(dòng)畫發(fā)生的頻次較低,將大禮物動(dòng)畫節(jié)點(diǎn)緩存起來不僅意義不大,還會(huì)造成內(nèi)存壓力過大。如圖4所示,在不清除大禮物節(jié)點(diǎn)的情況下,連續(xù)播放兩次大禮物動(dòng)畫會(huì)導(dǎo)致內(nèi)存占用顯著上升。
圖4 優(yōu)化前大禮物動(dòng)畫內(nèi)存占用圖
因此,對于大禮物動(dòng)畫節(jié)點(diǎn),應(yīng)該在需要播放大禮物動(dòng)畫的時(shí)候再創(chuàng)建,而且動(dòng)畫播放完成之后,應(yīng)該立即將節(jié)點(diǎn)以及相關(guān)的資源移除。值得注意的是,Cocos2d-x引擎在清除精靈幀緩存的時(shí)候并不會(huì)清除與精靈幀相關(guān)聯(lián)的圖片紋理緩存,必須手動(dòng)清除動(dòng)畫相關(guān)的圖片紋理緩存。優(yōu)化后的內(nèi)存占用情況如圖5所示。
圖5 優(yōu)化后大禮物動(dòng)畫內(nèi)存占用圖
2.4開發(fā)與調(diào)試
相比于原生動(dòng)畫開發(fā),使用Cocos2d-x游戲引擎開發(fā)動(dòng)畫除了具有跨平臺(tái)運(yùn)行和在線熱更新的好處以外,還能極大地提升開發(fā)效率。在原生動(dòng)畫的開發(fā)當(dāng)中,編譯源代碼的過程是相當(dāng)耗時(shí)的,每次修改完代碼都要經(jīng)歷漫長的編譯過程才能看到效果,這直接導(dǎo)致了動(dòng)畫開發(fā)效率的低下。Cocos2d-x動(dòng)畫的開發(fā)調(diào)試流程則要快捷得多,因?yàn)镃ocos2d-x支持JavaScript編程,使用JavaScript編寫的動(dòng)畫代碼可以直接在瀏覽器運(yùn)行,每次修改完代碼之后,只需要刷新瀏覽器即可看到效果。如果借助于一些自動(dòng)化工具,甚至可以做到編寫完代碼瀏覽器自動(dòng)刷新。
此外,Cocos2d-x定義的JavaScript API專門為JavaScript程序員做過優(yōu)化設(shè)計(jì),接口簡便易用,相比于Cocos2d-x C++ API而言,學(xué)習(xí)成本大大降低。
針對當(dāng)前直播類APP中原生動(dòng)畫開發(fā)方式的弊端,本文提出了基于Cocos2d-x的動(dòng)畫開發(fā)方案。使用Cocos2d-x引擎編寫的代碼具備跨平臺(tái)運(yùn)行、可在線熱更新以及調(diào)試方便等優(yōu)點(diǎn),但是在現(xiàn)有APP中集成Cocos2d-x引擎,勢必在一定程度上增加系統(tǒng)的復(fù)雜性。因此,必須做好架構(gòu)的設(shè)計(jì)。Cocos2d-x引擎擁有強(qiáng)大的動(dòng)畫API,但是不適合用來做復(fù)雜的UI布局和編寫業(yè)務(wù)邏輯,因此在架構(gòu)上只讓Cocos2d-x引擎負(fù)責(zé)動(dòng)畫的展現(xiàn),UI布局和業(yè)務(wù)邏輯交給原生APP負(fù)責(zé)。為了使動(dòng)畫在APP上運(yùn)行更加流暢,還需要對動(dòng)畫性能做一定的優(yōu)化工作。對于頻次高、內(nèi)存占用少的動(dòng)畫,可以通過緩沖池策略緩解CPU壓力;對于頻次低、內(nèi)存占用高的動(dòng)畫,則需要在動(dòng)畫結(jié)束之后將所有相關(guān)資源從內(nèi)存中清除以避免內(nèi)存占用持續(xù)升高。
[1]鄭高強(qiáng). Cocos2d-JS開發(fā)之旅:從HTML5到原生手機(jī)游戲[M].北京:電子工業(yè)出版社,2015.3.
[2]關(guān)東升. Cocos2d-x實(shí)戰(zhàn). JS卷:Cocos2d-JS開發(fā)[M]. 北京:清華大學(xué)出版社,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