【嘮叨】
粒子系統CCParticleSystem,第一次聽到這名詞,感覺好高級的樣子啊。
其實在遊戲中我們也經常能見到的,像燃燒的火焰、飄散的煙霧、爆炸、暴風雪、流星、雨水、閃電等等都是粒子特效。
給大家看一張甜美的粒子特效:
因爲粒子系統的知識比較複雜,所以在這裏,強烈建議大家下載一個粒子編輯器,通過編輯粒子特效,來學習粒子系統。
我就是藉助了以下這個“紅孩兒工具箱”,來學習粒子系統的。
【致謝】
http://blog.csdn.net/honghaier (提供了強大的“紅孩兒工具箱”)
http://goldlion.blog.51cto.com/4127613/767801 (提供了詳細的原理)
【小知識】
浮動值Var:表示隨機上下浮動的修正值。實際值 = 原始值 + 浮動值Var。
如:原始值爲5,浮動值Var爲2。那麼實際值取值範圍:3~7。
【Demo下載】
http://down.51cto.com/data/1869970
【3.x】
(1)去掉“CC”
(2)粒子位置模式 tPositionType 改爲強枚舉類型 ParticleSystem::PositionType::
// ParticleSystem::PositionType::FREE //自由模式: 不與發射器聯繫,自己走自己的路線 ParticleSystem::PositionType::RELATIVE //相對模式: 粒子發射器隨粒子節點的移動而移動 ParticleSystem::PositionType::GROUPED //相對模式: 粒子羣隨粒子發射器的移動而移動//
(3)發射器模式 kCCParticleModeGravity / kCCParticleModeRadius
改爲強枚舉類型:ParticleSystem::Mode::
// ParticleSystem::Mode::GRAVITY //重力發射器 ParticleSystem::Mode::RADIUS //半徑發射器//
(4)其他變化不大。
【CCParticleSystem】
CCParticleSystem爲粒子系統的主要類,它的父類爲CCNode和CCTextureProtocol。由此可見粒子系統包含了一張紋理圖片用於顯示。而它還有一個子類CCParticleSystemQuad,該類只是在父類的基礎上,又加了一些屬性。而我們主要關注的是CCParticleSystemQuad這個類的用法。
1、原理
首先來講講粒子系統的工作原理。
粒子系統主要由兩部分組成:粒子、粒子發射器。
粒子的生命週期:出生、成長、死亡。
(1)在引擎中存在一個粒子池,存放了待激活的粒子。發射器每次從粒子池中獲取一個粒子,然後計算賦予粒子初始的屬性(速度、大小、方向、生存時間等)後,將粒子發射出去。
(2)粒子被髮射出去後,會不斷地刷新來修正它的屬性。
(3)當粒子的生存時間結束後,粒子就會死亡,然後重新被粒子池回收,等待下一次的激活。
來個具體的粒子發射圖:
2、粒子屬性
粒子發射器每秒會發射許許多多的粒子,而每個粒子在發射時,都會被賦予粒子相關的屬性。另外值得注意的是:粒子被賦予的屬性並不是全部一樣的,發射器會根據原始值與浮動值Var進行設置。這樣就能保證每個粒子會有不同的展現效果。
浮動值Var:表示隨機上下浮動的修正值。實際值 = 原始值 + 浮動值Var。
如:原始值爲5,浮動值Var爲2。那麼實際值取值範圍:3~7。
3、發射器屬性
發射器有兩種類型:重力發射器模式、半徑發射器模式。
3.1、發射器共有屬性
3.2、重力發射器
3.3、半徑發射器
4、現成粒子特效
cocos2dx引擎中爲我們提供了一些粒子效果的類,這些類是爲了方便開發者直接用於表現某種粒子效果的。
如下列出11種粒子特效:
粒子特效類 | 中文名 | 特效圖 |
CCParticleExplosion | 爆炸特效 | |
CCParticleFire | 火焰特效 | |
CCParticleFlower | 花束特效 | |
CCParticleFireworks | 煙花特效 | |
CCParticleGalaxy | 星系特效 | |
CCParticleMeteor | 流星特效 | |
CCParticleRain | 下雨特效 | |
CCParticleSmoke | 煙霧特效 | |
CCParticleSnow | 下雪特效 | |
CCParticleSpiral | 漩渦特效 | |
CCParticleSun | 太陽特效 |
5、混合方式
參考:http://shahdza.blog.51cto.com/2410787/1547633
粒子發射器一般都會發射大量的粒子出來,必然會有許多的粒子重疊或者交叉在一起。
所以對於粒子紋理圖片的混合方式,在很大程度上影響了視覺效果。
使用方法如下舉例:
// //{ 源因子 , 混合因子 } ccBlendFunc cbl = { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }; emitter->setBlendFunc(cbl);//
6、粒子紋理
介紹粒子系統類的繼承關係時,其中包含了CCTextureProtocol這個紋理協議類。如果沒有紋理圖片的話,所有粒子將會是單調的色塊。如果想要精美的視覺效果,就要考慮在粒子效果中使用紋理了。
值得注意的是:不要因爲粒子會很小而忽略它的紋理圖片,如果沒有設置紋理屬性的具體值,那麼引擎就會設定一個默認正方形的紋理,多數情況下,效果是非常差的。最好的方式是使用一個球形的圖片,其透明度爲半透明的。
還有重要的一點:就是圖片的尺寸最好不要超過64像素*64像素。因爲貼圖尺寸越小,粒子效果就運行得越流暢,畫面也更加細膩。同時,由於粒子效果就是依靠粒子相互疊加產生的畫面效果。如果紋理過大的話,疊加太多就會變成了白色區域。
PS:粒子系統還可以在發生粒子的過程中,動態改變紋理貼圖,使用setTexture()。
通過如下例子來設置紋理:
// emitter->setTexture( CCTextureCache::sharedTextureCache()->addImage("HelloWorld.png") );//
【代碼實戰】
主要測試粒子特效的四種創建方式。
(1)使用代碼,創建重力發射器模式
(2)使用代碼,創建半徑發射器模式
(3)創建現成粒子特效
(4)使用plist文件,創建自定義的粒子特效(使用“紅孩兒工具箱”製作)
不建議使用:(1)、(2)。因爲這兩種方法太過繁瑣,且不容易看出效果。
建議使用 :(3)、(4)。方便、且有現成的特效製作工具。
1、創建重力發射器模式
不建議使用。
// void HelloWorld::testGravity() { CCPoint mysize = CCDirector::sharedDirector()->getVisibleSize(); CCParticleSystemQuad* quad = CCParticleSystemQuad::create(); this->addChild(quad,1,1); //紋理圖片 quad->setTexture( CCTextureCache::sharedTextureCache()->addImage("HelloWorld.png") ); //混合模式 ccBlendFunc cbl = { GL_SRC_ALPHA , GL_ONE}; quad->setBlendFunc(cbl); /********************/ /* 粒子屬性 */ /********************/ //粒子生命,單位:秒 quad->setLife(3); quad->setLifeVar(0.25); //大小,-1表示和初始大小一致 quad->setStartSize(100); quad->setStartSizeVar(0); quad->setEndSize(-1); quad->setEndSizeVar(0); //顏色,ccc4f:取值0~1 quad->setStartColor( ccc4f(192/255.0, 63/255.0, 63/255.0, 63/255.0) ); quad->setStartColorVar( ccc4f(0, 0, 0, 0) ); quad->setEndColor( ccc4f(0, 0, 0, 0) ); quad->setEndColorVar( ccc4f(0, 0, 0, 0) ); //旋轉角度 quad->setStartSpin(0); quad->setStartSpinVar(60); quad->setEndSpin(180); quad->setEndSpinVar(30); //發射角度 quad->setAngle(90); quad->setAngleVar(10); /********************/ /* 發射器子屬性 */ /********************/ //最大粒子個數 quad->setTotalParticles(1000); //粒子發射器持續時間,-1爲永久 quad->setDuration(-1); //發射速率 quad->setEmissionRate( quad->getTotalParticles()/quad->getLife() ); //發射器位置 quad->setPosition( mysize/2 ); quad->setPosVar( ccp(10,10) ); //重力模式 quad->setEmitterMode(kCCParticleModeGravity); //粒子位置模式 quad->setPositionType(kCCPositionTypeFree); //粒子速度 quad->setSpeed(60); quad->setSpeedVar(20); //重力加速度 quad->setGravity( ccp(0, 0) ); //徑向加速度 quad->setRadialAccel(0); quad->setRadialAccelVar(0); //切向加速度 quad->setTangentialAccel(0); quad->setTangentialAccelVar(0); }//
2、創建半徑發射器模式
不建議使用。
// void HelloWorld::testRadius() { CCPoint mysize = CCDirector::sharedDirector()->getVisibleSize(); CCParticleSystemQuad* quad = CCParticleSystemQuad::create(); this->addChild(quad,1,1); //紋理圖片 quad->setTexture( CCTextureCache::sharedTextureCache()->addImage("HelloWorld.png") ); //混合模式 ccBlendFunc cbl = { GL_SRC_ALPHA , GL_ONE}; quad->setBlendFunc(cbl); /********************/ /* 粒子屬性 */ /********************/ //粒子生命,單位:秒 quad->setLife(3); quad->setLifeVar(0.25); //大小,-1表示和初始大小一致 quad->setStartSize(20); quad->setStartSizeVar(0); quad->setEndSize(-1); quad->setEndSizeVar(0); //顏色,ccc4f:取值0~1 quad->setStartColor( ccc4f(192/255.0, 63/255.0, 63/255.0, 63/255.0) ); quad->setStartColorVar( ccc4f(0, 0, 0, 0) ); quad->setEndColor( ccc4f(0, 0, 0, 0) ); quad->setEndColorVar( ccc4f(0, 0, 0, 0) ); //旋轉角度 quad->setStartSpin(0); quad->setStartSpinVar(60); quad->setEndSpin(180); quad->setEndSpinVar(30); //發射角度 quad->setAngle(90); quad->setAngleVar(10); /********************/ /* 發射器子屬性 */ /********************/ //最大粒子個數 quad->setTotalParticles(1000); //粒子發射器持續時間,-1爲永久 quad->setDuration(-1); //發射速率 quad->setEmissionRate( quad->getTotalParticles()/quad->getLife() ); //發射器位置 quad->setPosition( mysize/2 ); quad->setPosVar( ccp(10,10) ); //環形模式 quad->setEmitterMode(kCCParticleModeRadius); //粒子位置模式 quad->setPositionType(kCCPositionTypeFree); //初始半徑 quad->setStartRadius(20); quad->setStartRadiusVar(1); //結束半徑,-1和初始大小一致 quad->setEndRadius(100); quad->setEndRadiusVar(1); //粒子圍繞初始點,每秒旋轉角度 quad->setRotatePerSecond(360); quad->setRotatePerSecondVar(1); }//
3、創建火焰粒子特效
無需添加紋理圖片Texture,可直接使用。
// void HelloWorld::testParticle() { CCParticleFire* quad = CCParticleFire::create(); this->addChild(quad,1,1); }//
4、創建自定義plist的粒子特效
plist粒子特效,可以通過“紅孩兒工具箱”進行製作。
// void HelloWorld::testPlist() { CCPoint mysize = CCDirector::sharedDirector()->getVisibleSize(); CCParticleSystemQuad* quad = CCParticleSystemQuad::create("1.plist"); quad->setPosition( mysize/2 ); this->addChild(quad,1,1); }//
5、運行結果
6、分析與總結
(1)明顯發現使用1、2方法創建粒子特效太過繁瑣,並且屬性值也不容易控制。
(2)推薦使用現有粒子特效,或者使用“紅孩兒工具箱”製作粒子特效。