【COCOS2DX-游戏开发之二四】 quick-cocos2dx
初窺 Quick-cocos2d-x
quick-cocos2d-x(后文簡(jiǎn)稱 quick)與 cocos2d-x 的關(guān)系,用一句話概括:quick 是 cocos2d-x 針對(duì) Lua 的豪華套裝威力加強(qiáng)版。
項(xiàng)目地址:quick-cocos2d-x?項(xiàng)目 Wiki:?wiki
那 quick 與 cocos2d-x 相比到底有什么區(qū)別,又有什么加強(qiáng)呢?這篇文章就是答案:
為什么會(huì)有 quick
cocos2d-x 是一個(gè)用 C++ 開(kāi)發(fā)的游戲引擎,其架構(gòu)設(shè)計(jì)和 API 基本上是照搬的 cocos2d-iphone(一個(gè)用 Objective-C 的 iOS 游戲開(kāi)發(fā)引擎)。
由于 C++ 對(duì)開(kāi)發(fā)人員要求較高,所以網(wǎng)龍科技利用 tolua++ 這個(gè)工具,將 cocos2d-x 的 C++ 接口轉(zhuǎn)為了 Lua 接口(這種將 C++ 接口導(dǎo)出為 Lua 接口的庫(kù)通常稱為 luabinding)。讓開(kāi)發(fā)者可以使用 Lua 這種簡(jiǎn)單易懂的腳本語(yǔ)言來(lái)編寫(xiě)游戲,從而大大提高開(kāi)發(fā)效率。
大概在 2012 年上半年,我們公司開(kāi)始使用 cocos2d-x + Lua 來(lái)開(kāi)發(fā)游戲。但是發(fā)現(xiàn)當(dāng)時(shí) cocos2d-x 對(duì) Lua 的支持還存在相當(dāng)多不完善的地方。所以我重寫(xiě)了整個(gè) luabinding 的支持代碼,解決了內(nèi)存泄露、只能使用全局函數(shù)做回調(diào)等問(wèn)題。
在 cocos2d-x 2.0 發(fā)布后,luabinding 又進(jìn)行了不少改進(jìn)和完善。截止到 cocos2d-x 2.1.4,整個(gè) luabinding 已經(jīng)可以說(shuō)是相當(dāng)穩(wěn)定了。所以《我是 MT》、《大掌門(mén)》這些賺錢(qián)像印錢(qián)的游戲,就紛紛采用 cocos2d-x + Lua 的解決方案了。
可惜 cocos2d-x 團(tuán)隊(duì)從 2012 年以來(lái)一直在強(qiáng)力推廣 cocos2d-x 的 JavaScript 解決方案,所以在 Lua 支持上基本上就沒(méi)有什么大動(dòng)作了。而從我們使用 Lua 解決方案的開(kāi)發(fā)商看來(lái),需要 luabinding 具備更強(qiáng)大的功能,因此這就是我們開(kāi)發(fā) quick 的最初原因。
quick 的目標(biāo):
quick 和 cocos2d-x 的差別
雖然 cocos2d-x luabinding 已經(jīng)很完善了,但是要開(kāi)發(fā)一個(gè)游戲,我們還需要做許多基礎(chǔ)工作。
-
將 luabinding 導(dǎo)出的 C++ 接口重新封裝成 Lua 風(fēng)格的接口是最基本的工作。重新封裝后的接口應(yīng)該更容易學(xué)習(xí)和使用,并且一些 C++ 和 Lua 之間數(shù)據(jù)格式轉(zhuǎn)換也應(yīng)該隱藏起來(lái)。而這就是 quick 里首先實(shí)現(xiàn)的目標(biāo)。
看看下面的代碼:
-- 載入 Sprite Sheet local frameCache = CCSpriteFrameCache:sharedSpriteFrameCache() frameCache:addSpriteFramesWithFile("Sprites.plist", "Sprites.png")-- 構(gòu)造一個(gè)幀動(dòng)畫(huà)序列 Run0001.png -> Run0010.png local frames = CCArray:create() for index = 1, 10 dolocal frameName = string.format("Run%04d.png", index)local frame = frameCache:spriteFrameByName(frameName)frames:addObject(frame) end-- 創(chuàng)建 CCSprite 對(duì)象 local firstFrame = tolua.cast(frames:objectAtIndex(0), "CCSpriteFrame") local sprite = CCSprite:createWithSpriteFrame(firstFrame)-- 在 CCSprite 之上播放動(dòng)畫(huà)(用 0.5 秒播放完 10 幀) local animation = CCAnimation:createWithSpriteFrames(frames, 0.5 / 10) sprite:runAction(CCRepeatForever:create(CCAnimate:create(animation)))這段代碼的功能在游戲中會(huì)反復(fù)出現(xiàn),所以通常會(huì)封裝成幾個(gè)簡(jiǎn)單的函數(shù)。而 quick 里封裝后的接口要完成同樣功能會(huì)使用如下代碼:
display.addSpriteFramesWithFile("Sprites.plist", "Sprites.png") local frames = display.newFrames("Run%04d.png", 1, 10) local sprite = display.newSpriteWithFrame(frames[1]) local animation = display.newAnimation(frames, 0.5 / 10) sprite:playAnimationForever(animation)通過(guò)這個(gè)對(duì)比,可以看出二次封裝是多么必要。而 quick 提供了一個(gè) Lua Framework,封裝了大量最常用的接口。
-
cocos2d-x 是一個(gè)功能完善的游戲引擎,但對(duì)于一個(gè)能掙錢(qián)的游戲來(lái)說(shuō),cocos2d-x 還缺少很多必須的功能。所以 quick 在 cocos2d-x 基礎(chǔ)上添加了更多游戲必須的功能,例如完善的 HTTP 和 Socket 網(wǎng)絡(luò)功能、數(shù)據(jù)加密解密、設(shè)備功能訪問(wèn)等等。
-
游戲的玩法做得差不多了,就需要開(kāi)始集成付費(fèi)充值、統(tǒng)計(jì)、社會(huì)化分享、好友鏈等各種第三方 SDK。
在 iOS 和 Android 平臺(tái)上做這些工作,傳統(tǒng)做法是分別編寫(xiě) Objective-C 和 Java 的接口代碼,然后再用 C++ 中轉(zhuǎn),借助 tolua++ 導(dǎo)出給 Lua 使用。這種做法不但繁瑣,而且像 Java 和 C++ 的交互存在相當(dāng)多的困難,所以開(kāi)發(fā)效率極低。
quick 針對(duì)這個(gè)問(wèn)題,特別開(kāi)發(fā)了 LuaObjectiveCBridge 和 LuaJavaBridge 兩個(gè)模塊。利用這兩個(gè)模塊,我們?cè)诮尤?SDK 時(shí),就不再需要 C++ 中轉(zhuǎn)層,也不需要 tolua++,由此省下的工作量相當(dāng)驚人。
而且 quick 的附屬項(xiàng)目會(huì)提供大量現(xiàn)成的 SDK 封裝,進(jìn)一步提高開(kāi)發(fā)效率,讓開(kāi)發(fā)商把主要的資源花在游戲玩法上。
-
在開(kāi)發(fā)過(guò)程中,需要不斷測(cè)試。而 cocos2d-x 自帶的 Windows 和 Mac 模擬器功能太簡(jiǎn)單。quick 特別開(kāi)發(fā)了功能完備的模擬器,讓整個(gè)游戲在開(kāi)發(fā)階段的大部分時(shí)間里都不需要借助真機(jī)就可以進(jìn)行(小伙伴們都知道,Android 真機(jī)調(diào)試那么是多么的蛋疼)。
看看 quick 華麗的模擬器吧 :)
-
除了上述內(nèi)容,quick 里還包含了物理引擎 Chipmunk 2D 的 Lua 封裝(相信我,你不可能找到比這個(gè)更容易使用的物理引擎接口)、骨骼動(dòng)畫(huà)播放(支持 DragonBones、CocoStudio)、高性能的 LuaJIT 虛擬機(jī)等等。
總結(jié)而言,quick 和 cocos2d-x 的主要區(qū)別有如下幾點(diǎn):
除了這些重大區(qū)別外,quick 還在細(xì)節(jié)上做了一些調(diào)整和完善。并且后續(xù)還會(huì)將來(lái)自 cocos2d-x 最新開(kāi)發(fā)分支(devel 3.0)的一些重要 bugfix 和有價(jià)值的新功能移植到 quick 中。
當(dāng)然,當(dāng) cocos2d-x 3.0 完全穩(wěn)定下來(lái)的時(shí)候,quick 也會(huì)做相應(yīng)的升級(jí)。
quick 由哪些部分組成
quick 由幾個(gè)主要部分組成:
- cocos2d-x:目前基于 cocos2d-x 2.1.4 版本
- tolua++:用于將 C++ 接口導(dǎo)出給 Lua 腳本使用
- LuaJIT:最快的 Lua 虛擬機(jī)
- cocos2d-x-extra:擴(kuò)展功能,包括數(shù)據(jù)加密編碼、網(wǎng)絡(luò)傳輸、設(shè)備功能訪問(wèn)等
- Chipmunk 2D:物理引擎,以及相應(yīng)的 cocos2d-x 和 Lua 封裝接口
- CSArmature:一個(gè)骨骼動(dòng)畫(huà)播放庫(kù),支持 DragonBones 和 CocoStudio 創(chuàng)建的骨骼動(dòng)畫(huà)
除此之外,還包含一些 Lua 的擴(kuò)展:
- lua_extensions:一些必備的 Lua 模塊,包括 JSON、ZLib、LuaFileSystem、LuaSocket 等
- LuaJavaBridge:簡(jiǎn)單的 Lua - Java 交互接口,簡(jiǎn)化 SDK 集成
- LuaObjectiveCBridge:簡(jiǎn)單的 Lua - Objective-C 交互接口
應(yīng)該選擇 Lua 還是 JavaScript
目前 cocos2d-x 支持兩種腳本語(yǔ)言的 binding,從我個(gè)人了解,各自的情況列表如下:
| 完全訪問(wèn) cocos2d-x API | YES | YES |
| iOS 平臺(tái) | YES | YES |
| Android 平臺(tái) | YES | YES |
| Windows 平臺(tái) | YES | YES |
| Mac 平臺(tái) | YES | YES |
| Linux 平臺(tái) | YES* | YES |
| HTML5 平臺(tái) | NO | YES |
| JIT 支持 | YES | YES |
| 編譯為字節(jié)碼 | YES | YES |
| 字節(jié)碼是否可以反編譯 | NO | NO |
| 運(yùn)行性能 | HIGH | LOW |
| 接入 SDK 工作量 | 簡(jiǎn)單 | 復(fù)雜,通過(guò) C++ 中轉(zhuǎn) |
| 導(dǎo)出自定義 C++ 類(lèi) | 簡(jiǎn)單 | 復(fù)雜 |
而我最看重其中幾點(diǎn):
-
運(yùn)行效率:LuaJIT 編譯的字節(jié)碼在 JIT 可用時(shí),運(yùn)行效率可以接近 C 的程度。而在 iOS 這種不支持 JIT 的環(huán)境里,Lua 的運(yùn)行效率比 JavaScript 高很多()。
-
是否容易擴(kuò)展:Lua 從設(shè)計(jì)時(shí)就是作為嵌入式語(yǔ)言來(lái)設(shè)計(jì)的,所以需要將某個(gè) C/C++ 接口導(dǎo)出給 Lua 使用,那是相當(dāng)輕松的事情。
-
源代碼保護(hù):LuaJIT 編譯的字節(jié)碼目前是無(wú)法反編譯的,因?yàn)?LuaJIT 在編譯時(shí)不是 1:1 直接轉(zhuǎn)換源代碼,而是對(duì)源代碼做了相當(dāng)多的深入優(yōu)化。LuaJIT 編譯出的字節(jié)碼體積是 Lua 編譯字節(jié)碼的三分之一,由此可見(jiàn)優(yōu)化程度。
客觀的說(shuō),JavaScript binding 最大的優(yōu)勢(shì)是以前大量的 JS 前端開(kāi)發(fā)人員可以很容易的上手,而且支持 HTML5 平臺(tái)。但如果從手游體驗(yàn)來(lái)說(shuō),Lua 的運(yùn)行效率是很重要的優(yōu)勢(shì)。
怎么入門(mén) quick
東西再好,學(xué)不會(huì)也是白搭,所以這篇文章的重點(diǎn)是這個(gè)部分,前面都是廣告 :)
學(xué)習(xí) Lua
Lua 是一種簡(jiǎn)單易用的語(yǔ)言。學(xué)習(xí)這種語(yǔ)言最好的方式就是花幾天時(shí)間寫(xiě)代碼,然后在命令行中運(yùn)行。
重點(diǎn):
- table 在 Lua 中是一種萬(wàn)能數(shù)據(jù)結(jié)構(gòu),既可以表示數(shù)組,又可以表示名值對(duì)。這和 PHP 里的 array 一樣。唯一的區(qū)別在于 table 用作數(shù)組時(shí),第一個(gè)元素的下標(biāo)是從 1 開(kāi)始。
- function 在 Lua 里是 first-class 類(lèi)型,也就是說(shuō)你可以把一個(gè) function 當(dāng)做普通值,傳遞來(lái)傳遞去,這和其他函數(shù)式編程語(yǔ)言是一樣的,例如 JavaScript。
- Lua 里用 table 配合 metatable 實(shí)現(xiàn)面向?qū)ο蟆S捎?C++ 對(duì)象導(dǎo)出到 Lua 里后就是這樣的機(jī)制,所以這個(gè)一定要搞明白。
- 搞清楚在定義方法和調(diào)用方法的時(shí)候,用“.”和“:”的區(qū)別。
嘗試修改和完善 quick 的各個(gè)示例程序
用 quick-x-player(quick 里牛叉的模擬器)運(yùn)行 sample 目錄里的各個(gè)例子,無(wú)差別爆改。改一點(diǎn)就按 F5(Mac 上按 CMD+R)刷新模擬器看看效果(做過(guò) Web 前端的童鞋感動(dòng)吧),要不了幾天就成熟練工了。
最常遇到的問(wèn)題:
-
這個(gè)方法返回了一個(gè)什么對(duì)象?
因?yàn)?quick 里對(duì) C++ 接口進(jìn)行了二次封裝,所以一些框架的方法返回的對(duì)象不一定很明確。但大多數(shù)可以從方法名上推測(cè)出來(lái):
- display.newSprite() 創(chuàng)建 CCSprite 對(duì)象
- display.newFrames() 創(chuàng)建包含多個(gè) CCSpriteFrame 對(duì)象的數(shù)組
- ui.newImageMenuItem() 創(chuàng)建 CCImgeMenuItem 對(duì)象
- ui.newMenu() 創(chuàng)建 CCMenu 對(duì)象
實(shí)在看不出來(lái),那就去 framework 目錄里翻源代碼吧。
-
這個(gè)方法是干嘛的?
首先,從 framework 里找。找不到就去 cocos2d-x 里找。還找不到,那就是 cocos2d-x-extra 或者第三方庫(kù)提供的方法。這里強(qiáng)烈推薦 Sublime Text 這個(gè)超神的編輯器,全文檢索神馬的完全不在話下。
-
為什么代碼沒(méi)有預(yù)期的效果?
不管是 Lua 還是 quick,當(dāng)前的版本都非常非常穩(wěn)定。所以遇到這種情況,不要首先懷疑語(yǔ)言特征或者引擎,而是多做測(cè)試,看看問(wèn)題到底是怎么發(fā)生的。
-
在哪里尋求幫助?
目前 quick 還沒(méi)有專門(mén)的社區(qū),所以如果你想尋求幫助,最快捷的途徑就是 QQ 群:284148017 。當(dāng)然,不會(huì)有誰(shuí)成天沒(méi)事兒在那里義務(wù)解答,所以 QQ 群更多是交流經(jīng)驗(yàn)的地方。未來(lái),quick 會(huì)建立自己的社區(qū),方便大家的交流。
熟悉 cocos2d-x API
本質(zhì)上,quick 是 cocos2d-x 的一個(gè)增強(qiáng)版本,所以熟悉 cocos2d-x API 是基本要求。好在 cocos2d-x 目前已經(jīng)有相當(dāng)豐富的學(xué)習(xí)資料,即便是 C++ 代碼的,改寫(xiě)為 Lua 也非常簡(jiǎn)單,也就語(yǔ)法的區(qū)別而已。
這個(gè)階段可以用 quick 里的 CoinFlip 示例為基礎(chǔ),添加更多玩法或功能。CoinFlip 已經(jīng)具備一個(gè)完整游戲的雛形,所以能夠在 CoinFlip 中自在添加功能時(shí),也就達(dá)到可以獨(dú)立開(kāi)發(fā)游戲的程度了。
學(xué)習(xí)使用擴(kuò)展功能和第三方 Lua 擴(kuò)展
quick 里包含了相當(dāng)豐富的擴(kuò)展庫(kù),從支付到網(wǎng)絡(luò)服務(wù)都應(yīng)有盡有。而這些功能也是游戲從項(xiàng)目變成產(chǎn)品時(shí)必須的,所以在熟練掌握擴(kuò)展功能可以大大提高開(kāi)發(fā)效率,避免重復(fù)勞動(dòng)。
在學(xué)習(xí)擴(kuò)展功能時(shí),要了解這個(gè)擴(kuò)展功能是基于什么開(kāi)源項(xiàng)目來(lái)開(kāi)發(fā)的,這樣才能找到有針對(duì)性的學(xué)習(xí)資源。例如 LuaSocket、LuaFileSystem 等 Lua 擴(kuò)展、Chipmunk 2D 物理引擎等等,它們的用法在各自項(xiàng)目的網(wǎng)站上都能找到。
導(dǎo)出自己的 C++ 對(duì)象到 Lua
有時(shí)候需要編寫(xiě)一些 C++ 對(duì)象,然后導(dǎo)出給 Lua 使用。這里可以參考 lib/cocos2dx_extra/extra/luabinding 里的 *.tolua 文件,將 C/C++ 頭文件轉(zhuǎn)為 tolua++ 需要的文件,然后借助 quick 中附帶的腳本編譯成 luabinding 接口。
在 quick 項(xiàng)目的 wiki 中,也有其他相關(guān)的文檔可以參考。
集成第三方 SDK
quick 有一個(gè)附屬倉(cāng)庫(kù)?quick-cocos2d-x-plugins,其中包含了一些 SDK 的接口文件。參考 sample/luajavabridge 示例和這些接口文件,很容易就能完成 SDK 的集成。
后續(xù) quick 也會(huì)提供更多的 SDK 接口,以及相應(yīng)的示例代碼。
- END -
文章鏈接:http://dualface.github.io/blog/2013/07/31/quick-first-time/
總結(jié)
以上是生活随笔為你收集整理的【COCOS2DX-游戏开发之二四】 quick-cocos2dx的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql加速搜索_巧用MySQL AH
- 下一篇: Unity_Shader高级篇_14.1