一、粒子系統簡介:
粒子系統最早出現在80年代,主要用於解決由大量按一定規則運動(變化)的微小物質在計算機上的生成和顯示問題。Particle System的應用非常廣泛,大的可以模擬原子彈爆炸,星雲變化,小的可以模擬水波、火焰、煙火、雲霧等,而這些自然現象用常規的圖形算法是很難逼真再現的。
Particle System可以說是一種基於物理模型來解決問題的方法,它的核心不在於如何顯示,而在用於對微小物質模型的規則提取。
粒子運動(變化)的規則可以很簡單也可以很復雜,這取決你所模擬的對象。舉例來說,在對FireWorks(煙火)的模擬中,我們可以讓煙火由上百個小的粒子組成,每個粒子都具有以下一些屬性及其規則(對各個屬性施加不同的規則,就可以獲得不同形態的煙火):
Coordinate(坐標)
在煙火爆炸的時刻,每個粒子都有一個相同的初始坐標,隨着時間的推移,粒子的新坐標將由它的舊坐標和加速度來求得
Velocity(速度)
每個粒子都有一個隨機產生的初始速度,粒子的新速度由加速度和空氣阻尼來求得
Acceleration(加速度)
在煙火中,每個粒子的加速度都等於重力加速度
Color(顏色)
粒子顏色取決於粒子的速度或生命值的大小
Life(生命值)
每個粒子都有一個初始的隨機生命值,這個值將隨着時間的推移而逐漸減小,直到等於0
你會發現,Particle System中的粒子與C++中類的概念有些類似,實際上你完全可以將它當成類來處理,一個粒子就是一個類的實例對象,只不過有時在涉及程序優化的具體細節上,你需要放棄使用類,而使用簡單而快速的緊湊代碼。
Particle System雖然在處理大量單獨粒子的運動(變化)上很有用處,但是一涉及到需要考慮粒子間相互作用的場合,因為這時的計算量呈粒子數量的指數級增長,它就顯得有些力不從心了。比如在模擬有相互引力作用下的大量星體的運動,大量粒子的相互碰撞等。
二、粒子系統的生命周期
首先,從粒子池中獲取一個粒子,
然后計算賦予初始屬性后,發射他。
在粒子飛行過程中,不斷的刷新來修正他的屬性。
粒子死亡后,回歸粒子池。
三、例子相關屬性
Variance 浮動值:表示隨機上下浮動的修正值,實際值由原始值+浮動值組成,例如Lifespan=5,Lifespan Variance=1 那么隨機出來的結果就是4~6
四、發射器相關屬性
發射器有兩種,一種是重力發射器(用於實現在重力條件下的粒子運動),另一種是放射發射器(用於實現在無重力下的粒子運動)。
五、紋理Texture
如果沒有貼圖的話,所有粒子將會是單調的色塊。粒子的貼圖沒有具體限制,可以是灰度圖,也可以是一張具體的圖片。但要小於64x64pixel
六、cocos2d-x實現Particle System
第一種方法:
CCParticleSystem* m_emitter;
m_emitter = CCParticleFireworks::node();
m_emitter->retain();
this->addChild(m_emitter, 10);
m_emitter->setTexture( CCTextureCache::sharedTextureCache()->addImage(“image.png”) );
m_emitter->setPosition(ccp( 489, 320));
m_emitter = CCParticleFireworks::node();
m_emitter->retain();
this->addChild(m_emitter, 10);
m_emitter->setTexture( CCTextureCache::sharedTextureCache()->addImage(“image.png”) );
m_emitter->setPosition(ccp( 489, 320));
第二種方法:
CCParticleSystem* m_emitter;
m_emitter = new CCParticleSystemQuad();
m_emitter->initWithTotalParticles( 50);
this->addChild(m_emitter, 10);
m_emitter->setTexture( CCTextureCache::sharedTextureCache()->addImage(s_stars1) );
m_emitter->setDuration(- 1);
// gravity
m_emitter->setGravity(CCPointZero);
// angle
m_emitter->setAngle( 90);
m_emitter->setAngleVar( 360);
// speed of particles
m_emitter->setSpeed( 160);
m_emitter->setSpeedVar( 20);
// radial
m_emitter->setRadialAccel(- 120);
m_emitter->setRadialAccelVar( 0);
// tagential
m_emitter->setTangentialAccel( 30);
m_emitter->setTangentialAccelVar( 0);
// emitter position
m_emitter->setPosition( CCPointMake( 160, 240) );
m_emitter->setPosVar(CCPointZero);
// life of particles
m_emitter->setLife( 4);
m_emitter->setLifeVar( 1);
// spin of particles
m_emitter->setStartSpin( 0);
m_emitter->setStartSizeVar( 0);
m_emitter->setEndSpin( 0);
m_emitter->setEndSpinVar( 0);
// color of particles
ccColor4F startColor = { 0.5f, 0.5f, 0.5f, 1.0f};
m_emitter->setStartColor(startColor);
ccColor4F startColorVar = { 0.5f, 0.5f, 0.5f, 1.0f};
m_emitter->setStartColorVar(startColorVar);
ccColor4F endColor = { 0.1f, 0.1f, 0.1f, 0.2f};
m_emitter->setEndColor(endColor);
ccColor4F endColorVar = { 0.1f, 0.1f, 0.1f, 0.2f};
m_emitter->setEndColorVar(endColorVar);
// size, in pixels
m_emitter->setStartSize( 80.0f);
m_emitter->setStartSizeVar( 40.0f);
m_emitter->setEndSize(kParticleStartSizeEqualToEndSize);
// emits per second
m_emitter->setEmissionRate(m_emitter->getTotalParticles()/m_emitter->getLife());
// additive
m_emitter->setIsBlendAdditive( true);
m_emitter = new CCParticleSystemQuad();
m_emitter->initWithTotalParticles( 50);
this->addChild(m_emitter, 10);
m_emitter->setTexture( CCTextureCache::sharedTextureCache()->addImage(s_stars1) );
m_emitter->setDuration(- 1);
// gravity
m_emitter->setGravity(CCPointZero);
// angle
m_emitter->setAngle( 90);
m_emitter->setAngleVar( 360);
// speed of particles
m_emitter->setSpeed( 160);
m_emitter->setSpeedVar( 20);
// radial
m_emitter->setRadialAccel(- 120);
m_emitter->setRadialAccelVar( 0);
// tagential
m_emitter->setTangentialAccel( 30);
m_emitter->setTangentialAccelVar( 0);
// emitter position
m_emitter->setPosition( CCPointMake( 160, 240) );
m_emitter->setPosVar(CCPointZero);
// life of particles
m_emitter->setLife( 4);
m_emitter->setLifeVar( 1);
// spin of particles
m_emitter->setStartSpin( 0);
m_emitter->setStartSizeVar( 0);
m_emitter->setEndSpin( 0);
m_emitter->setEndSpinVar( 0);
// color of particles
ccColor4F startColor = { 0.5f, 0.5f, 0.5f, 1.0f};
m_emitter->setStartColor(startColor);
ccColor4F startColorVar = { 0.5f, 0.5f, 0.5f, 1.0f};
m_emitter->setStartColorVar(startColorVar);
ccColor4F endColor = { 0.1f, 0.1f, 0.1f, 0.2f};
m_emitter->setEndColor(endColor);
ccColor4F endColorVar = { 0.1f, 0.1f, 0.1f, 0.2f};
m_emitter->setEndColorVar(endColorVar);
// size, in pixels
m_emitter->setStartSize( 80.0f);
m_emitter->setStartSizeVar( 40.0f);
m_emitter->setEndSize(kParticleStartSizeEqualToEndSize);
// emits per second
m_emitter->setEmissionRate(m_emitter->getTotalParticles()/m_emitter->getLife());
// additive
m_emitter->setIsBlendAdditive( true);
第三種方法:
CCParticleSystemQuad *system =
new CCParticleSystemQuad();
system->initWithFile( " Images/SpinningPeas.plist "); // plist文件可以通過例子編輯器獲得
system->setTextureWithRect(CCTextureCache::sharedTextureCache()->addImage( " Images/particles.png ")
, CCRectMake( 0, 0, 32, 32));
addChild(system, 10);
system->setPosition
system->initWithFile( " Images/SpinningPeas.plist "); // plist文件可以通過例子編輯器獲得
system->setTextureWithRect(CCTextureCache::sharedTextureCache()->addImage( " Images/particles.png ")
, CCRectMake( 0, 0, 32, 32));
addChild(system, 10);
system->setPosition