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