cocos2dx 粒子系統CCParticleSystem

【嘮叨】

    粒子系統CCParticleSystem,第一次聽到這名詞,感覺好高級的樣子啊。i_f32.gif

    其實在遊戲中我們也經常能見到的,像燃燒的火焰、飄散的煙霧、爆炸、暴風雪、流星、雨水、閃電等等都是粒子特效。

    給大家看一張甜美的粒子特效:

wKiom1QDNBzj9IYzAAIduD0EWgc443.gif

    因爲粒子系統的知識比較複雜,所以在這裏,強烈建議大家下載一個粒子編輯器,通過編輯粒子特效,來學習粒子系統。

    我就是藉助了以下這個“紅孩兒工具箱”,來學習粒子系統的。

wKioL1QEcDHCSmagAAOnZyku2N8610.jpg

【致謝】

    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這個類的用法。

wKiom1QDRL2ySa0RAAB3E8pel4U629.jpg

1、原理

    首先來講講粒子系統的工作原理。

    粒子系統主要由兩部分組成:粒子粒子發射器

    粒子的生命週期:出生、成長、死亡。

    (1)在引擎中存在一個粒子池,存放了待激活的粒子。發射器每次從粒子池中獲取一個粒子,然後計算賦予粒子初始的屬性(速度、大小、方向、生存時間等)後,將粒子發射出去。

    (2)粒子被髮射出去後,會不斷地刷新來修正它的屬性。

    (3)當粒子的生存時間結束後,粒子就會死亡,然後重新被粒子池回收,等待下一次的激活。

wKioL1QECSSgjpeKAADb_BXNzm0765.jpg

    來個具體的粒子發射圖:

wKioL1QEDROhCtOaAAC1ZbM30x0928.jpg

2、粒子屬性

    粒子發射器每秒會發射許許多多的粒子,而每個粒子在發射時,都會被賦予粒子相關的屬性。另外值得注意的是:粒子被賦予的屬性並不是全部一樣的,發射器會根據原始值與浮動值Var進行設置。這樣就能保證每個粒子會有不同的展現效果。

    浮動值Var:表示隨機上下浮動的修正值。實際值 = 原始值 + 浮動值Var。

    如:原始值爲5,浮動值Var爲2。那麼實際值取值範圍:3~7。

wKioL1QEK8SQZSvjAATSneo4-cY762.jpg

3、發射器屬性

    發射器有兩種類型:重力發射器模式、半徑發射器模式。

    3.1、發射器共有屬性

wKioL1QEbeLgkH8WAAXgZ7s00Y4897.jpg

    3.2、重力發射器

wKioL1QEbrrwKbW7AAOY4mNgRnM563.jpg

    3.3、半徑發射器

wKiom1QEbtLSkUWHAAL2ODJMw3s396.jpg

4、現成粒子特效

    cocos2dx引擎中爲我們提供了一些粒子效果的類,這些類是爲了方便開發者直接用於表現某種粒子效果的。

    如下列出11種粒子特效:

粒子特效類中文名特效圖
CCParticleExplosion爆炸特效wKioL1QElTnxsvynAAOhhjdFpnQ245.gif
CCParticleFire火焰特效wKioL1QElXfxvPr4AAJ5EL27VA4957.gif
CCParticleFlower花束特效

wKioL1QElpCBGs-fAAM5uk4Fkwo114.gif

CCParticleFireworks煙花特效wKiom1QElpDCz8dVAAHRRjeRu8U947.gif
CCParticleGalaxy星系特效wKiom1QElpCTS1fBAAHGotw6_5g755.gif
CCParticleMeteor流星特效wKioL1QElpGA-JsyAALJgHqUsUY422.gif
CCParticleRain下雨特效wKiom1QElpHic2uAAADwya6Jcl8519.gif
CCParticleSmoke煙霧特效wKioL1QElxuBhfVlAAHNxnAtaDc841.gif
CCParticleSnow下雪特效wKioL1QElpHxVbpCAAcTynw2yOY759.gif
CCParticleSpiral漩渦特效wKiom1QElpKgVyqnAA-UOFdZTZ4915.gif
CCParticleSun太陽特效wKioL1QElpLT2r3LAACvjfQFuCQ333.gif

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、運行結果

wKiom1QE1dGzrfN7AASA9ZQKHOY175.gif    wKioL1QE1dLTxDDPAAXbM5kR9yg836.gif

wKiom1QE1dKwp7AJAAhLNkpvsiI400.gif    wKioL1QE1dODQ03FAALwqKCEi1k382.gif

6、分析與總結

    (1)明顯發現使用1、2方法創建粒子特效太過繁瑣,並且屬性值也不容易控制。

    (2)推薦使用現有粒子特效,或者使用“紅孩兒工具箱”製作粒子特效。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章