cocos2dx[2.x](19)--粒子系统CCParticleSystem

【唠叨】

粒子系统CCParticleSystem,第一次听到这名词,感觉好高级的样子啊。i_f32.gif
其实在游戏中我们也经常能见到的,像燃烧的火焰、飘散的烟雾、爆炸、暴风雪、流星、雨水、闪电等等都是粒子特效。
给大家看一张甜美的粒子特效:

这里写图片描述

因为粒子系统的知识比较复杂,所以在这里,强烈建议大家下载一个粒子编辑器,通过编辑粒子特效,来学习粒子系统。
我就是借助了以下这个“红孩儿工具箱”,来学习粒子系统的。

这里写图片描述

【致谢】
http://blog.csdn.net/honghaier (提供了强大的“红孩儿工具箱”)
http://goldlion.blog.51cto.com/4127613/767801 (提供了详细的原理)

【小知识】

浮动值Var:表示随机上下浮动的修正值。实际值 = 原始值 + 浮动值Var。
           如:原始值为5,浮动值Var为2。那么实际值取值范围:3~7。

【Demo下载】
https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E7%B2%92%E5%AD%90%E7%B3%BB%E7%BB%9FCCParticleSystem

【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)推荐使用现有粒子特效,或者使用“红孩儿工具箱”制作粒子特效。
转载网址:http://blog.51cto.com/shahdza/1547636

猜你喜欢

转载自blog.csdn.net/qq_34240791/article/details/80254139