粒子系统1:简介&工具使用

一、粒子系统简介:

 
每个粒子都有一个初始的随机生命值,这个值将随着时间的推移而逐渐减小,直到等于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));
复制代码
 
第二种方法:
复制代码
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.5f0.5f0.5f1.0f};
 m_emitter->setStartColor(startColor);
   
 ccColor4F startColorVar = { 0.5f0.5f0.5f1.0f};
 m_emitter->setStartColorVar(startColorVar);
   
 ccColor4F endColor = { 0.1f0.1f0.1f0.2f};
 m_emitter->setEndColor(endColor);
   
 ccColor4F endColorVar = { 0.1f0.1f0.1f0.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 
复制代码
 
 



























直接使用工具来感受一下粒子系统的强大威力吧。

网络上有很多粒子编辑器,大多数都是收费的。magicalsoft提供了一个免费的粒子编辑器(该工具目前只有mac版本),界面如下:

我们将针对这个编辑器来讲解粒子系统。其他的和这个功能差不多。 

 

第一部分:为什么要有粒子系统?

粒子系统在游戏中被大量的应用于游戏特效,能够极大的提高游戏的画面观感。

使用帧动画也可以实现特效效果。但是缺点也很明显:

1.画面效果弱

2.细节不自然

3.修改不方便

以前,手机性能不强的时候,使用粒子系统是非常蛋疼的。现在手机硬件配置和软件支持(OpenGL)的大幅度强化,让强大的粒子系统有了展示的机会。

 

第二部分:粒子系统生命周期

粒子一旦诞生都要经历完整的生命周期:

首先,从粒子池中获取一个粒子,

然后计算赋予初始属性后,发射他。

在粒子飞行过程中,不断的刷新来修正他的属性。

粒子死亡后,回归粒子池。

 

第三部分:粒子相关属性

Variance 浮动值:表示随机上下浮动的修正值,实际值由原始值+浮动值组成,例如Lifespan=5Lifespan Variance=1那么随机出来的结果就是46

 

第四部分:发射器相关属性

发射器有两种,一种是重力发射器(用于实现在重力条件下的粒子运动),另一种是放射发射器(用于实现在无重力下的粒子运动)。

 


第五部分:OpenGL混合

#1神马是混合?

混合就是把两种颜色混在一起。具体一点,就是把某一像素位置原来的颜色和将要画上去的颜色,通过某种方式混在一起,从而实现特殊的效果。

假设我们需要绘制这样一个场景:透过红色的玻璃去看绿色的物体,那么可以先绘制绿色的物体,再绘制红色玻璃。在绘制红色玻璃的时候,利用“混合”功能,把将要绘制上去的红色和原来的绿色进行混合,于是得到一种新的颜色,看上去就好像玻璃是半透明的。 

#2混合中的术语

前面我们已经提到,混合需要把原来的颜色和将要画上去的颜色找出来,经过某种方式处理后得到一种新的颜色。这里把将要画上去的颜色称为“源颜色”,如上例中的红色;把原来的颜色称为“目标颜色”,如上例中的绿色。

OpenGL会把源颜色和目标颜色各自取出,并乘以一个系数(源颜色乘以的系数称为“源因子”,目标颜色乘以的系数称为“目标因子”),然后相加,这样就得到了新的颜色。(也可以不是相加,新版本的OpenGL可以设置运算方式,包括加、减、取两者中较大的、取两者中较小的、逻辑运算等,但我们这里为了简单起见,不讨论这个了) 

#3混合公式

下面用数学公式来表达一下这个运算方式。假设源颜色的四个分量(指红色,绿色,蓝色,alpha值)是(Rs, Gs, Bs, As),目标颜色的四个分量是(Rd, Gd, Bd, Ad),又设源因子为(Sr, Sg, Sb, Sa),目标因子为(Dr, Dg, Db, Da)。则混合产生的新颜色可以表示为:

(Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da)

当然了,如果颜色的某一分量超过了1.0,则它会被自动截取为1.0,不需要考虑越界的问题。 

#4各种混合因子

在OpenGL中,源因子和目标因子是可以通过glBlendFunc函数来进行设置的。glBlendFunc有两个参数,前者表示源因子,后者表示目标因子。这两个参数可以是多种值,下面介绍比较常用的几种。

GL_ZERO:      表示使用0.0作为因子,实际上相当于不使用这种颜色参与混合运算。

GL_ONE:       表示使用1.0作为因子,实际上相当于完全的使用了这种颜色参与混合运算。

GL_SRC_ALPHA:表示使用源颜色的alpha值来作为因子。

GL_DST_ALPHA:表示使用目标颜色的alpha值来作为因子。

GL_ONE_MINUS_SRC_ALPHA:表示用1.0减去源颜色的alpha值来作为因子。

GL_ONE_MINUS_DST_ALPHA:表示用1.0减去目标颜色的alpha值来作为因子。

除此以外,还有GL_SRC_COLOR(把源颜色的四个分量分别作为因子的四个分量)、GL_ONE_MINUS_SRC_COLOR、GL_DST_COLOR、GL_ONE_MINUS_DST_COLOR等,前两个在OpenGL旧版本中只能用于设置目标因子,后两个在OpenGL旧版本中只能用于设置源因子。新版本的OpenGL则没有这个限制,并且支持新的GL_CONST_COLOR(设定一种常数颜色,将其四个分量分别作为因子的四个分量)、GL_ONE_MINUS_CONST_COLOR、GL_CONST_ALPHA、GL_ONE_MINUS_CONST_ALPHA。另外还有GL_SRC_ALPHA_SATURATE。新版本的OpenGL还允许颜色的alpha值和RGB值采用不同的混合因子。但这些都不是我们现在所需要了解的。毕竟这还是入门教材,不需要整得太复杂~

举例来说:

如果设置了glBlendFunc(GL_ONE, GL_ZERO);,则表示完全使用源颜色,完全不使用目标颜色,因此画面效果和不使用混合的时候一致(当然效率可能会低一点点)。如果没有设置源因子和目标因子,则默认情况就是这样的设置。

如果设置了glBlendFunc(GL_ZERO, GL_ONE);,则表示完全不使用源颜色,因此无论你想画什么,最后都不会被画上去了。(但这并不是说这样设置就没有用,有些时候可能有特殊用途)

如果设置了glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);,则表示源颜色乘以自身的alpha值,目标颜色乘以1.0减去源颜色的alpha值,这样一来,源颜色的alpha值越大,则产生的新颜色中源颜色所占比例就越大,而目标颜色所占比例则减小。这种情况下,我们可以简单的将源颜色的alpha值理解为“不透明度”。这也是混合时最常用的方式。

如果设置了glBlendFunc(GL_ONE, GL_ONE);,则表示完全使用源颜色和目标颜色,最终的颜色实际上就是两种颜色的简单相加。例如红色(1, 0, 0)和绿色(0, 1, 0)相加得到(1, 1, 0),结果为黄色。

注意:

所谓源颜色和目标颜色,是跟绘制的顺序有关的。假如先绘制了一个红色的物体,再在其上绘制绿色的物体。则绿色是源颜色,红色是目标颜色。如果顺序反过来,则红色就是源颜色,绿色才是目标颜色。在绘制时,应该注意顺序,使得绘制的源颜色与设置的源因子对应,目标颜色与设置的目标因子对应。不要被混乱的顺序搞晕了。


#5混合举例

glBlendFunc(GL_ONE, GL_ZERO)

 

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

 

glBlendFunc(GL_ONE, GL_ONE)

 

 

第六部分:纹理Texture

如果没有贴图的话,所有粒子将会是单调的色块。在当前这个工具中,只需要点击Texture区域即可添加贴图。粒子的贴图没有具体限制,可以是灰度图,也可以是一张具体的图片。但要小于64x64pixel

 

第七部分:绘制粒子的代码

绘制粒子的代码非常简单,由于magicalsoft的粒子编辑器,不能导出缺省的Texture。所以我准备了现成的meteor.plist和meteor.png。

将这两个导入到xcode中的resource里,然后在当前Scene中添加如下代码: 

  
  
  1. CCParticleSystem *meteor=CCParticleSystemQuad::particleWithFile("meteor.plist"); 
  2.  
  3.  meteor->setPosition(ccp(size.width/2,size.height/2)); 
  4.  
  5.  this->addChild(meteor); 

运行效果:

参考文献:

《cocos2d Game Develop》第九章 粒子系统

知易Cocos2D-iPhone 游戏开发教程007 粒子系统

OPENGL混合(ZZ):http://hi.baidu.com/asky007/blog/item/1f8bcded3da7dd4979f0555e.html


 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值