最新文章
Cocos2d-x游戏开发实例详解7:对象释放时机
03-25 13:59
Cocos2d-x游戏开发实例详解6:自动释放池
03-25 13:55
Cocos2d-x游戏开发实例详解5:神奇的自动释放
03-25 13:49
Cocos2d-x游戏开发实例详解4:游戏主循环
03-25 13:44
Cocos2d-x游戏开发实例详解3:无限滚动地图
03-25 13:37
Cocos2d-x游戏开发实例详解2:开始菜单续
03-25 13:32
cocos2d-x 粒子系统介绍
一、粒子系统的介绍
粒子系统最早出现在 20 世纪 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
如果没有贴图,所有粒子将是单调的色块。粒子的贴图没有具体限制,可以是灰度图,也可以是具体的图片,但尺寸要小于 64x64 像素。
六、Cocos2d-x 实现 Particle System
在 Cocos2d-x 中,有以下三种实现粒子系统的方法:
第一种方法
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.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(...); // 原代码此处未完整设置位置