[cocos2d-x·总结]关于cocos2d-x几种画图方法的用法与思考
簡(jiǎn)述情況:
·游戲運(yùn)行平臺(tái):Android
·Cocos2d-x引擎版本:cocos2d-1.0.1-x-0.11.0
?
有時(shí)做項(xiàng)目可能會(huì)需要用到畫(huà)圖功能,比如最近的《你畫(huà)我猜》。Cocos2d-x有各種畫(huà)圖方法,下面我主要說(shuō)說(shuō)最近做項(xiàng)目時(shí)用過(guò)的:
?
CCRenderTexture
自己的理解
CCRenderTexture類似一張空白的“畫(huà)布“,用戶通過(guò)自定義筆刷(CCSprite*),在touch事件中把筆刷的移動(dòng)痕跡“記錄”起來(lái),從而“畫(huà)”出各種藝術(shù)效果。記錄方法很簡(jiǎn)單,首先CCRenderTexture調(diào)用自己的begin()函數(shù),開(kāi)啟“記錄”功能,然后調(diào)用筆刷->visit()把自己”畫(huà)“在這張畫(huà)布上,最后CCRenderTexture調(diào)用end()結(jié)束記錄,那就OK了。
這里我想CCRenderTexture是通過(guò)把筆刷的紋理疊加到自己的紋理(Texture)里,而不是不斷創(chuàng)建新紋理,所以消耗比較低,即使畫(huà)得很頻繁,幀數(shù)也能保持穩(wěn)定,是個(gè)很贊的類。
CCRenderTexture由于只要begin()開(kāi)啟“記錄”功能后,任何之后的CCNode*對(duì)象只要調(diào)用了visit(),就能將自己“畫(huà)”在其身上。所以,一般游戲的截屏功能,完全可以使用CCRenderTexture的來(lái)實(shí)現(xiàn),具體可以看tests里例子,cocos2d-x已經(jīng)提供了相關(guān)例子,看看源代碼就能搞明白的。
優(yōu)點(diǎn)
用CCRenderTexture可以很簡(jiǎn)單的實(shí)現(xiàn)出理想的畫(huà)圖效果(只要搞一張很小的筆刷圖,然后用CCSprite載入來(lái),再適當(dāng)調(diào)用一個(gè)CCSprite的visit()就行了),幀數(shù)消耗低,還很方便實(shí)現(xiàn)出游戲的截屏功能,做《你畫(huà)我猜》這種項(xiàng)目,第一想到的應(yīng)該就是它了。
缺點(diǎn)
由于每個(gè)Android手機(jī)的硬件或者OpenGL版本不一樣,導(dǎo)致有些手機(jī)用CCRenderTexture會(huì)出現(xiàn)花屏,比如HTC。就算是官方提供的tests例子也難逃一花屏,這個(gè)致命的缺點(diǎn)導(dǎo)致用它來(lái)實(shí)現(xiàn)的《你畫(huà)我猜》不能跨手機(jī),比較坑爹…
這個(gè)Bug我想不是cocos2d-x引擎的問(wèn)題,有牛人說(shuō)是因?yàn)門(mén)exture在重復(fù)畫(huà)導(dǎo)致的(只畫(huà)一次沒(méi)問(wèn)題,所以截屏功能應(yīng)該不受影響),也許是每臺(tái)Android手機(jī)的OpenGL不一樣吧,所以問(wèn)題一直沒(méi)得到解決,只能等cocos2d-x或者有其他牛人以后可以把它Fixed掉。
因?yàn)榛ㄆ羻?wèn)題,現(xiàn)階段不推薦使用(如果有牛人解決了花屏問(wèn)題,請(qǐng)教教我,謝謝)
(花屏參考圖)
例子
CCRenderTexture大概是大家比較熟悉的,tests里也有相關(guān)例子,要知道用法直接看tests的源代碼就可以了,效果如圖:
?
?
?
用OpenGL-ES實(shí)現(xiàn)畫(huà)圖
自己的理解
OpenGL-ES是OpenGL的精簡(jiǎn)版,由于太精簡(jiǎn),很多OpenGL常用的函數(shù)都被“簡(jiǎn)”掉了,導(dǎo)致有很多網(wǎng)上一搜一大把的畫(huà)圖算法用不上。所以用OpenGL-ES畫(huà)圖,這個(gè)感覺(jué)難度非常高。
在cocos2d-x中,OpenGL-ES一般在draw()這個(gè)函數(shù)里面調(diào)用其相關(guān)函數(shù)。當(dāng)然cocos2d-x也封裝了幾個(gè)常用的畫(huà)圖函數(shù):ccDrawLine,ccDrawCircle等,當(dāng)然cocos2d-x也提供了例子,在tests里可以輕松找到。
優(yōu)點(diǎn)
暫時(shí)沒(méi)想到,因?yàn)槲冶旧韺?duì)OpenGL-ES不熟…
缺點(diǎn)
實(shí)現(xiàn)難度大可以攔截一大批人了,感覺(jué)。因?yàn)椴荒芟馛CRenderTexture那樣在touch事件中進(jìn)行繪圖,所以一般會(huì)把要畫(huà)的CCPoint在touch事件的記錄下來(lái),然后在draw()這個(gè)函數(shù)里遍歷之,以實(shí)現(xiàn)繪圖效果。
移動(dòng)過(guò)的點(diǎn)一般都要保存下來(lái),注意的是要全部保存,如果只保存當(dāng)前點(diǎn)的話,draw()就只會(huì)畫(huà)一個(gè)點(diǎn),畫(huà)出來(lái)的效果就像一個(gè)“光點(diǎn)”跟隨的鼠標(biāo)移動(dòng),而不是繪圖。一般畫(huà)一幅畫(huà),鼠標(biāo)都會(huì)拖動(dòng)出N個(gè)點(diǎn),如果只是簡(jiǎn)單的vector<CCPoint>保存的話,vector會(huì)超大,draw中遍歷它也很耗時(shí),導(dǎo)致沒(méi)一會(huì)幀數(shù)就掉光了。具體怎么保存看數(shù)據(jù)結(jié)構(gòu)吧,同事以線段作為數(shù)據(jù)結(jié)構(gòu)來(lái)記錄點(diǎn),這樣消耗不大,幀數(shù)也能保持穩(wěn)定。
另外一個(gè)缺點(diǎn)就是如果算法實(shí)現(xiàn)不好,畫(huà)出來(lái)的效果很坑爹,同事的線段法雖然能很流暢的畫(huà)線,但是鋸齒問(wèn)題很嚴(yán)重,開(kāi)了OpenGL的抗鋸齒也沒(méi)效果。如果對(duì)OpenGL-ES很熟而且算法也很牛的話,也許draw()是最快最好的一種畫(huà)圖法了。
最后還一個(gè)超坑爹的缺點(diǎn):draw()在Google那臺(tái)三星手機(jī)上,始終畫(huà)在最頂層顯示,然后線條就會(huì)把游戲UI遮蓋住了,無(wú)論怎么設(shè)置z-Order都沒(méi)用,估計(jì)是Google的三星手機(jī)的OpenGL-ES做過(guò)什么特殊處理吧,導(dǎo)致“坑爹啊…”
(萬(wàn)惡的鋸齒…)
例子
Cocos2d-x提供的相關(guān)例子(DrawPrimitivesTest),常見(jiàn)的畫(huà)直線、畫(huà)圓、畫(huà)Bezier線等,都有函數(shù)提供,具體還是自己打開(kāi)tests看看源代碼吧,這里就不詳述了。
(DrawPrimitivesTest)
?
CCSpriteBatchNode
自己的理解
用CCSpriteBatchNode生成的CCSprite共用一個(gè)紋理,這樣的好處是生成很多相同的CCSprite很高效,幀數(shù)可以很高很穩(wěn)定。由于這個(gè)特點(diǎn),用來(lái)實(shí)現(xiàn)粒子效果是一個(gè)很好的選擇,不過(guò)我還沒(méi)有看過(guò)cocos2d-x粒子系統(tǒng)的實(shí)現(xiàn),這里不做推測(cè),以免誤導(dǎo)大家。關(guān)于CCSpriteBatchNode的用法當(dāng)然還是tests里面有,有興趣的朋友可以自己看看。
優(yōu)點(diǎn)
由于draw()實(shí)現(xiàn)難度太高,而CCRenderTexture又有花屏的問(wèn)題,所以嘗試用CCSpriteBatchNode來(lái)實(shí)現(xiàn)畫(huà)圖,繪圖效果很不錯(cuò),因?yàn)槭鞘褂肅CSprite做自定義筆刷嘛。幀數(shù)保持58-60,很穩(wěn)定(如果只是單純的創(chuàng)建CCSprite*,然后addChild到Layer里,掉幀會(huì)很嚴(yán)重的)
缺點(diǎn)
雖然CCSpriteBatchNode效果很不錯(cuò),不過(guò)也有一個(gè)致命的缺點(diǎn),就是CCSpriteBatchNode*對(duì)象不能addChild太多的CCSprite*對(duì)象,同事做了一下實(shí)驗(yàn),大概addChild到16000+個(gè)CCSprite后,CCSpriteBatchNode就不能addChild了,也就是說(shuō),畫(huà)圖畫(huà)到16000+個(gè)點(diǎn)后,畫(huà)筆就“沒(méi)墨水”,導(dǎo)致鼠標(biāo)再怎么拖都沒(méi)效果。
查看了一下源代碼,大概是CCSpriteBatchNode在addChild時(shí)會(huì)重新分配內(nèi)存,當(dāng)需要分配的內(nèi)存很大時(shí),回導(dǎo)致內(nèi)存分配失敗,從而CCSpriteBatchNode會(huì)將這次addChild無(wú)效掉。
解決思路有一個(gè),就是來(lái)個(gè)計(jì)數(shù),當(dāng)CCSpriteBatchNode它addChild到10000個(gè)后,用CCRenderTexture截個(gè)圖保存當(dāng)前的畫(huà)圖記錄,然后清空CCSpriteBatchNode和把計(jì)數(shù)置零,再來(lái)畫(huà)圖。這個(gè)操作會(huì)有延遲,所以沒(méi)有實(shí)現(xiàn)。
?
CCRibbon
自己的理解
CCRibbon應(yīng)該說(shuō)是一個(gè)線段集吧,與上述方法不同的是,它只能是單一顏色。就是說(shuō),你將它setColor為紅,那么你畫(huà)過(guò)的線條就全部為紅,為藍(lán)的話,則線條全部為藍(lán)。
生成一個(gè)CCRibbon*對(duì)象需要指定:筆刷的寬度,筆刷的圖片,線段的長(zhǎng)度,筆刷的顏色等參數(shù)(Fade最后這個(gè)參數(shù)暫時(shí)還沒(méi)搞懂意思…)。
CCRibbon提供addPointAt(CCPoint?location,?float?width),將點(diǎn)以多寬加入到CCRibbon中,這里cocos2d-x對(duì)這個(gè)點(diǎn)的大小進(jìn)行計(jì)算,從而使線條達(dá)到“頭尾窄,身體寬”的效果。這個(gè)可以說(shuō)是優(yōu)點(diǎn)也可以說(shuō)是缺點(diǎn)吧,“頭尾窄,身體寬”看起來(lái)比較像筆刷,不過(guò)想做出均勻的畫(huà)筆就不行了。
優(yōu)點(diǎn)
幀數(shù)穩(wěn)定,筆刷效果不錯(cuò)。因?yàn)镃CRibbon也是用draw()進(jìn)行畫(huà)圖,所以不用擔(dān)心CCRenderTexture那樣的花屏問(wèn)題,CCRibbon目前感覺(jué)是比較理想的畫(huà)圖方法了。
缺點(diǎn)
如果在(100,100)點(diǎn)上一個(gè)點(diǎn),然后跑去(400,400)再點(diǎn)一個(gè)點(diǎn),CCRibbon會(huì)自動(dòng)將兩個(gè)點(diǎn)連起來(lái),如果用戶想做出平常畫(huà)圖那種“刷刷刷“的排線法,CCRibbon就不行了。解決方法就是每次TouchBegan都生成一個(gè)CCRibbon,這樣就不會(huì)出現(xiàn)這個(gè)問(wèn)題了,不過(guò)生成太多的CCRibbon不知道會(huì)不會(huì)出現(xiàn)其他問(wèn)題,比如CCSpriteBatchNode那個(gè)…
由于CCRibbon是單一顏色的,所以想畫(huà)彩色圖是不行的。解決方法當(dāng)然還是像上面那樣,生個(gè)多個(gè)CCRibbon*對(duì)象,每個(gè)CCRibbon*對(duì)象的顏色不同就行了。
最后感覺(jué)不太人性化的就是畫(huà)筆只能“頭尾窄,身體寬“,如果想畫(huà)出”頭身尾均勻“的線條,用CCRibbon也許做不了。
暫時(shí)還沒(méi)編到手機(jī)看效果,所以上面出現(xiàn)的問(wèn)題,也許CCRibbon也會(huì)出現(xiàn)…
例子
Cocos2d-x沒(méi)有直接給出CCRibbon的例子,所以這個(gè)不能夠在tests上看到使用方法,不過(guò)自己稍稍嘗試一下就行了,用法挺簡(jiǎn)單。下面是用CCRibbon畫(huà)的一個(gè)Q版的自己…
轉(zhuǎn)載于:https://www.cnblogs.com/j1223jesus/archive/2012/10/17/2727090.html
總結(jié)
以上是生活随笔為你收集整理的[cocos2d-x·总结]关于cocos2d-x几种画图方法的用法与思考的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: iOS 真机测试
- 下一篇: 14档箱车没有一档了怎么回事?