cocos2d-x並不是一個適合網游客戶端(mmo)的游戲引擎,越是大型游戲,這個小引擎就越無法駕馭(雖然它非常受歡迎)。 之前我在原來的公司使用的是自主研發的C3引擎,已經對外開放(尚未開源),后面如果我有提到c3引擎,那么指的就是這個2.5d游戲引擎。
我想起我上個月剛離職的時候,c3的首席研究員(應該也是引擎圈內的一個大牛)對我說cocos2d-x沒有什么技術含量,我還不以為然,當時我想的是,如果我自己開發一個游戲,首選必然是cocos2d-x。但是真正到新的公司接觸了使用cocos2d-x開發的一個類似神仙道的mmo才感覺cocos2d-x對於一個mmo引擎來說,差的很多。與c3相比,差就差在幾年,十余款mmo,上千位開發者的檢驗。雖然cocos2d-x的開發社區很龐大,但是它適合初學者去開發一個憤怒的小鳥、水果忍者,並不適合一個網游公司去開發一個mmo。雖然基於cocos2d-x有很多不錯的mmo,比如忘仙、神仙道。但是我認為那是一群牛x的開發者通過自己的努力彌補了cocos2d-x的不足。
可以認為我不是一個牛人,但是一個團隊能有一個牛人就已經萬幸了,能有兩個就可遇而不可求了,一個好的游戲引擎比如c3正是被我們這些普通開發者來使用,它可以不次時代,可以不面向對象,但是它會非常易於使用,並且非常難被誤用。
牢騷發完了,下面是具體的優化:
1、去掉libxml2,改用rapidxml來解析xml文件。 rapidxml簡直是一個大殺器,解析xml的速度甚至比純文本解析和json格式還要快。其解析速度比libxml2快5倍,即便cocos2d-x中使用的是sax模型,而rapidxml是dom模型,使用rapidxml依然要快非常多。我們的游戲是所有配置文件都用xml來描述,其實大可不必,但是為了跟網頁版本配置統一,方便今后的維護,暫時沒有對配置格式進行修改。而cocos2d-x底層對xml使用最頻繁的地方就是Plist文件的解析了。ios平台下還好,NSDictionary速度也很快(但是依然比rapidxml慢一倍),但是android下效果就非常明顯了。游戲啟動時間大大縮短。 所以,為什么cocos2d-x還要用libxml2呢?
2、游戲資源打包。 這個雖然是可以自己擴展的,但是卻是需要引擎提供支持的。因為所有的圖片讀取都是屬於引擎的內部代碼。 當然不是所有的游戲都需要資源打包,但是一個實用(mmo向)的游戲引擎這個是必然要考慮的。 這一塊兒牽扯到很多東西,比如游戲資源更新,資源讀取規則,讀取失敗后的異常處理,多線程加載時的同步機制等等。
3、修改CCAssert,增加日志記錄功能。 作為一個游戲引擎,cocos2d-x內部代碼很不健壯,很多資源不存在或者是不小心的誤用都會讓程序掛掉。 這個對一個mmo來說是不可接受的。 CCAssert原來是一個簡單的assert,這個在ios和android下就直接掛掉了,后面雖然修改為CCMessageBox的提示,但是依然不夠方便,因為這些彈出框都很卡很慢。接觸過mmo客戶端開發的應該都有體會資源不存在是經常發生的事情,尤其是大家一起開發功能的時候,資源總是最后才正確且完整。 這個時候記錄個log不就完了。而cocos2d-x卻並沒有提供任何Log記錄功能(實際文件Log而不是開發時用的CCLog)。 而引擎內部有大量的Assert,斷定文件一定是存在的,斷定某個配置一定是正確的,斷定某個Frame一定是存在的,這個造成的問題就是一旦有配置錯誤,那么程序很可能就崩潰掉了。而作為一個mmo,尤其是已經對外發布的情況下,這個時候出現表現異常(比如圖片不顯示)而不是崩潰會更加合理。
4、資源異步加載。雖然cocos2d-x有提供Texture的資源異步加載,但是這並不夠用。 我們修改為這樣的形式,CCSpriteCache緩存圖片的時候異步加載圖片,這個時候可以獲取到正確的CCSprite,只不過里面的CCTexture並沒有附上一個正確的紋理id,當圖片加載完畢,這個id就正確了,那么CCSprite在下一次Draw的時候自然就會渲染出正確的圖片(這里要做下判斷,如果紋理id不正確那么就不進行渲染操作)。 還有需要注意的就是只有一個線程加載圖片是不夠用的,根據需要可能要開3~5個線程來加載圖片,才會起到異步加載圖片的最佳體驗。 當然,如果僅僅是怕加載圖片卡主主線程而不關心加載速度,那么就不需要這么麻煩了。
5、添加一個快速渲染的CCFont,無論是哪個平台生成字形紋理的過程都是非常慢的。如果一個mmo中有大量的文本、聊天等等,光生成字形的時間可能就要500~600ms,那這個游戲給人的感覺就是時不時一卡一卡的。 這個新的CCFont思路非常簡單,生成字形的時候一個文字一個文字的進行生成,把生成的字形保存到一個512*512的紋理上,然后渲染的時候取這個生成好的字形進行繪制。
6、計划中: 人物圖片使用骨骼動畫切片處理,這個其實應該比什么js腳本更應該加到引擎內部。這個要提供的不僅僅是代碼的支持,這個是從生產到結果的一站式技術支持。 不能引導生產流程的引擎不能說是游戲引擎,不能成為生產線的游戲引擎不能說是游戲引擎。
優化進行中。。。。。。。
最后再牢騷下,我敢打賭cocos2d-x的js腳本支持並不是一個正確的選擇,如果是吸引html的開發者,我勉強認同cocos2d-html5,但是說實話,用html來開發網頁游戲在幾年內都不會是一個正確選擇。而cocos2d-html5更像是給html開發人員的玩具,並且悲劇的是這個玩具還有些難,大多數html開發者無法掌握這個玩具,只能用它寫寫斗地主之類的小游戲。有能力用它寫出捕魚達人的開發者要么是頂尖的html開發者,要么會像我一樣更習慣用c++來寫代碼。
正確的跨網頁平台方向應該是像c3或者是unity3d一樣,內部使用llvm把c++代碼直接編譯成flash或html5代碼,這樣現有的游戲只要經過非常簡單的移植就可以在網頁上面跑了。像unity3d那樣支持js固然不錯,但是這個不是必須的,我如果用unity3d,我選擇腳本語言會是c#而不會是js,相信很多游戲開發者都會做出這樣的選擇。所以cocos2d-x費了那么大力氣搞js,完全是走彎路了。有這個時間還不如把發布做好,把c#支持加進來(不加也無所謂,lua也湊合,就比c#慢幾倍而已)。如果cocos2d-x不能在mmo相關功能上提供更多的支持的話,那么它對我而言就是一個玩具,而不是一個強力武器
