cocos2d-x出來(lái)很長(zhǎng)時(shí)間了,受到的評(píng)價(jià)還是很不錯(cuò)的,有很多創(chuàng)業(yè)團(tuán)隊(duì)被它的跨平臺(tái)特性吸引,開(kāi)始用它來(lái)做IOS/Android上的游戲。雖然cocos2d-x已經(jīng)足夠優(yōu)秀,程序員的工作卻還有很多,而作為一個(gè)研發(fā)團(tuán)隊(duì),有件事情必須在項(xiàng)目開(kāi)始之前就考慮清楚:
換皮/山寨/原創(chuàng)不久之前,一個(gè)換皮團(tuán)隊(duì)的主程跟我抱怨說(shuō)老板不明白為什么他們的程序部可以只用一個(gè)月就讓產(chǎn)品上線但增加一個(gè)系統(tǒng)兩個(gè)月都搞不定。是的,換皮的效率優(yōu)勢(shì)的確明顯,但策劃是不甘寂寞的,所以無(wú)論是換皮還是山寨,策劃會(huì)讓你們的研發(fā)在某一階段退化到原創(chuàng)。一旦回歸原創(chuàng),代碼的結(jié)構(gòu)將會(huì)變得非常重要,它直接影響程序員修改代碼的效率。遺憾的是,在這種快節(jié)奏的研發(fā)環(huán)境下,程序員已經(jīng)沒(méi)有精力管這些了。你拿到手的換皮代碼,它的原作者也是如此。
拯救程序員與策劃和美工一樣,程序員也曾經(jīng)熱愛(ài)游戲,甚至更加熱愛(ài),但在入行多年以后的他們的心中,游戲究竟變成了什么呢?
你是否見(jiàn)證過(guò)這樣的場(chǎng)面:
經(jīng)理:策劃,你的數(shù)值做完了嗎?
策劃:做完了,Excel發(fā)給程序員了。
經(jīng)理:美術(shù)A,你的UI做完了嗎?
美術(shù)A:做完了,所有圖片打包發(fā)給程序員了。
經(jīng)理:美術(shù)B,你的動(dòng)畫(huà)做完了嗎?
美術(shù)B:做完了,所有序列幀打包發(fā)給程序員了。
。。。。。。
如果你沒(méi)見(jiàn)識(shí)過(guò),說(shuō)明你還算幸運(yùn),不過(guò)據(jù)我所知,很多小團(tuán)隊(duì)就是這樣的,流程中所有責(zé)任不明確的部分都被推給了程序員,因?yàn)橹挥谐绦騿T知道該怎么往下進(jìn)行。
這不是策劃或美工的錯(cuò),事實(shí)上他們有勁使不上也很著急,一些cocos2d的工具能稍微緩解一下這類問(wèn)題,但還遠(yuǎn)遠(yuǎn)不夠。我們需要的是一套完整的,為當(dāng)前項(xiàng)目量身定做的編輯器,不過(guò)對(duì)于程序員來(lái)說(shuō),額外開(kāi)發(fā)這樣的編輯器還不如之前的那些工作省事兒呢。
通用的編輯器框架
我不要求編輯器要像RPGMaker或者魔獸3那樣把腳本指令都逐個(gè)可視化了,但至少策劃的數(shù)值可以敲進(jìn)去,美術(shù)的動(dòng)畫(huà)可以導(dǎo)進(jìn)去,UI的布局可以在里邊擺好,地圖上的單位可以擺好,所有資源的名稱可以起好。。。。。。
為了以最快速度得到一個(gè)為游戲量身定做的編輯器,我做了一個(gè)通用的cocos2d-x編輯器框架,用的是cocos2d-x2.0.1和wxWidget2.9.3。我為CCObject類增加了一個(gè)Serialize接口,根據(jù)調(diào)用者的不同,這個(gè)函數(shù)可以做三件完全不同的事:
1.讀XML
2.寫(xiě)XML
3.生成PropertyGrid編輯器。
所以每當(dāng)你開(kāi)始一個(gè)新的游戲,只要把你派生類的Serialize函數(shù)寫(xiě)好,你的編輯器差不多就已經(jīng)完成了。
Serialize函數(shù)大體上應(yīng)該是這個(gè)樣子:
void CCSprite::Serialize(Serializer* s, void *data)
{
CCNode::Serialize(s,data);
s->Image(data, "Texture", m_pobTexture);
s->Rect(data, "Rect", m_obRect);
s->Point(data, "Offset",m_obUnflippedOffsetPositionFromCenter);
s->Size(data, "Size", m_tContentSize);
s->Bool(data, "Rotated", m_bRectRotated);
}
元件
元件是實(shí)例的模板,它本身也是實(shí)例,只不過(guò)它還包含所有的子節(jié)點(diǎn)(如果元件是CCNode的派生類),編輯器是以元件為單位進(jìn)行編輯的。
這個(gè)元件是商店物品列表中的一項(xiàng),它本身是一個(gè)CCMenuItemLabel,它包含5個(gè)子節(jié)點(diǎn),有4個(gè)需要在腳本中調(diào)用,要設(shè)置好它們的實(shí)例名,然后為這個(gè)元件添加一個(gè)函數(shù)
這個(gè)函數(shù)傳入了一個(gè)物品實(shí)例item,根據(jù)它的屬性來(lái)初始化界面,其實(shí)代碼可以更簡(jiǎn)潔的,為了好懂就這么寫(xiě)了。元件的腳本要在編輯器里寫(xiě),全局腳本需要新建一個(gè)與文檔同名的Lua文件。
這是全局腳本中的一段代碼,列出商店中的所有物品,我改寫(xiě)了CCMenu的alignItemsHorizontally函數(shù),讓它能按照行優(yōu)先的方式格狀排列,三個(gè)參數(shù)分別是列間距,行間距,最大列數(shù)。列優(yōu)先的函數(shù)與它是對(duì)稱的。同時(shí)我讓CCMenu本身支持了滾動(dòng)和裁減,不必再用CCScrollView,
最終效果是這樣的:
其他的界面也用類似的方法來(lái)做,很簡(jiǎn)單
腳本:最天然的指令隊(duì)列和場(chǎng)景棧
Lua很有名,以至于很多普通玩家都知道它,但作為程序員的你真的會(huì)用Lua嗎?
“用Lua開(kāi)發(fā)游戲有很多好處,比如它可以節(jié)省編譯時(shí)間?!蔽也恢挂淮慰吹竭@樣的言論,看得我欲哭無(wú)淚。
我認(rèn)為既然你選擇Lua作為腳本語(yǔ)言,應(yīng)該充分利用它的特性,它可以極大地簡(jiǎn)化你的代碼,或者讓你的代碼結(jié)構(gòu)變得完全不同。舉個(gè)例子,比如你想讓一個(gè)菜單fadeOut之后從父節(jié)點(diǎn)刪除,用C++的話需要把一個(gè)CCScaleTo和一個(gè)CCCallFunc組成CCSequence,然后在回調(diào)中刪除菜單,這個(gè)代碼就很糟糕,尤其是當(dāng)Sequence很長(zhǎng),或者是你想讓更了解該寫(xiě)什么的人來(lái)寫(xiě)這部分代碼的時(shí)候(比如讓劇情策劃寫(xiě)人物對(duì)白),這種方式就顯得太不人性化了。
腳本語(yǔ)言最大的優(yōu)勢(shì)就是可調(diào)度,你可以隨時(shí)中斷/恢復(fù)腳本的運(yùn)行,這與線程無(wú)關(guān)。上邊的例子,用Lua可以寫(xiě)成:
WaitForAction( menu:runAction(CCScaleTo:create(0.5,0)) );
在WaitForAction內(nèi)部,腳本被掛起,直到傳入的Action結(jié)束才會(huì)跳出。這樣寫(xiě)的好處就是一系列的指令可以緊挨著寫(xiě)在一起,保證了代碼的邏輯性和可讀性。
你也可以把等待Action結(jié)束換成等待用戶點(diǎn)擊按鈕,比如一個(gè)城鎮(zhèn)的代碼可以寫(xiě)成:
while 1 do
切換場(chǎng)景(城鎮(zhèn));
locals =等待用戶點(diǎn)擊按鈕();
if s =="下一關(guān)" then
進(jìn)入游戲(level+1);
elseif s =="酒館" then
進(jìn)入酒館();
elseif s =="商店" then
進(jìn)入商店();
else
break;
end
end
這段代碼看上去跟游戲的流程設(shè)計(jì)圖沒(méi)什么兩樣,甚至可以交給策劃來(lái)寫(xiě)。注意最外層的while循環(huán),它的作用是讓用戶從酒館或商店出來(lái)的時(shí)候能回到城鎮(zhèn)這個(gè)場(chǎng)景繼續(xù)做出選擇。
小結(jié)
關(guān)于編輯器內(nèi)部的介紹就說(shuō)這么多了,以后主要是針對(duì)編輯器的使用者發(fā)些教程。第一版會(huì)附帶風(fēng)之紋章的游戲模板一同放出,敬請(qǐng)期待
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。