在之前学习动画时,是通过多张图的切换去模拟焰火的效果,但是现在通过粒子系统就不用那么麻烦了
cocos2d 中内置了很多粒子特技
比如:火焰,流星,银河,雪花,雨滴,旋涡
代码可以指定效果范围,夹角,速度,粒子寿命,粒子大小,效果持续时间等等
来看看没有特技的一张图:加上暴雨:
一般使用步骤
- 创建粒子
- addChild()
常用方法:
- setGravity(Vec2(0,-500));// 粒子重力方向,这和场景的重力是独立的,互不影响
- setRadialAccel(100);// 径向加速度
- setPosVar(Vec2(1000, 0));// 发射点坐标可变相对位置
- setEmissionRate(1000); // 一次发射的粒子数
- setTotalParticles(10000);//总共可用粒子数
- setDuration(-1);// -1 表示特效一直有,其他正数表示特效持续时间
- setScale(1.5);//粒子放大倍数
- setLife(3);//粒子生命周期
- setLifeVar(3);// 在周期的基础上±3 也就是最终粒子的生命周期是 0-6秒的
- setAngle(10);//设置粒子角度
- setAngleVar(3);// 设置粒子可变角度 ,现在也就是 10-3 ~10+3
雨滴 ParticleRain
上代码:
#include "HelloWorldScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
USING_NS_CC;
using namespace cocostudio::timeline;
PhysicsWorld * world;
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
// auto scene = Scene::create();
auto scene = Scene::createWithPhysics();
world = scene->getPhysicsWorld();
scene->getPhysicsWorld()->setGravity(Vec2(0,-980));
//world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
// 1. super init first
if ( !Layer::init() )
{
return false;
}
//"Rain960x640.jpg"
auto bgNode = Sprite::create("Rain960x640.jpg");
bgNode->setAnchorPoint(Vec2(0, 200));
addChild(bgNode);
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
// 下雨特效
ParticleRain * rain = ParticleRain::create();
rain->setGravity(Vec2(0,-500));// 粒子重力方向,这和场景的重力是独立的,互不影响
//->setRadialAccel(100);// 径向加速度
rain->setPosVar(Vec2(1000, 0));// 发射点坐标可变相对位置
//rain->setAutoRemoveOnFinish(true);
rain->setEmissionRate(1000); // 一次发射的粒子数
rain->setTotalParticles(10000);//总共可用粒子数
rain->setDuration(-1);// -1 表示特效一直有,其他正数表示特效持续时间
//rain->setScale(1.5);
rain->setLife(3);//粒子生命周期
rain->setLifeVar(3);// 在周期的基础上+-3 也就是最终粒子的生命周期是 0-6秒的
//rain->setAngle(-30);
addChild(rain);
return true;
}
蜡烛: ParticleFire
代码:
//1 蜡烛 *******************************************
auto candle = Sprite::create("CandleHolder.png");
candle->setAnchorPoint(Vec2(0.5, 0));
candle->setPosition(visibleSize.width/2,0);
addChild(candle);
// 火焰特效
ParticleFire * fire = ParticleFire::create();
fire->setPosVar(Vec2(10,0));// 设置粒子发射点位置范围,(0,0)表示就一个点,如果是(20,0)
// 则表示 x是在 (-20,20)区间,y 都为0的位置 (这是相对位置)
fire->setSpeed(40);
fire->setLife(3);
fire->setEmissionRate(50);
fire->setLifeVar(3);
fire->setAngleVar(10);
fire->setPosition(visibleSize / 2+Size(-40,140));
addChild(fire);
火箭尾焰: ParticleSystemQuad
使用 .plist 文件创建
其他使用方式参见此博客
https://blog.csdn.net/aa4790139/article/details/8124781上代码:
#include "HelloWorldScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
USING_NS_CC;
using namespace cocostudio::timeline;
PhysicsWorld * world;
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
// auto scene = Scene::create();
auto scene = Scene::createWithPhysics();
world = scene->getPhysicsWorld();
scene->getPhysicsWorld()->setGravity(Vec2(0,600));// 这里给整个环境设置重力,用以给火箭加速
//world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
// 1. super init first
if ( !Layer::init() )
{
return false;
}
//"Rain960x640.jpg"
auto bgNode = Sprite::create();
bgNode->setAnchorPoint(Vec2(0, 200));
addChild(bgNode);
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
// 2 飞机尾焰************************
auto rocket = Sprite::create("Rocket.png");
rocket->setPosition(visibleSize.width/2,10);
addChild(rocket);
PhysicsBody * rocketBody = PhysicsBody::createBox(rocket->getContentSize());
rocket->setPhysicsBody(rocketBody);
//
ParticleSystemQuad * sq = ParticleSystemQuad::create("particle_texture.plist");
sq->setPosition(rocket->getPosition()+Size(0,-60));
PhysicsBody * sqBody = PhysicsBody::createBox(sq->getContentSize());
sq->setPhysicsBody(sqBody);
rocketBody->setCategoryBitmask(0);
//rocketBody->setVelocity(Vec2(0, 100));
// sqBody->setVelocity(Vec2(0, 100));// 不设置速度,依靠反向重力加速
sq->setTotalParticles(1000);//总共粒子数1000,是循环使用的
sq->setEmissionRate(100);//粒子发射率,比如每秒放出100个
sq->setPosVar(Vec2(0, 0));
sq->setAngleVar(0);
// sq->setAngle(-60);
addChild(sq);
// 将粒子与火箭绑定
PhysicsJoint *joint = PhysicsJointDistance::construct(rocketBody, sqBody, Vec2(0.5, 0), Vec2(0.5, 1));
world->addJoint(joint);
return true;
}
其他特效还有:
| 特效类名 | 含义 |
|---|---|
| ParticleExplosion | 爆炸 |
| ParticleFireWorks | 额,这个暂时没用到,是v字型喷出的,像是喷泉 |
| ParticleGalaxy | 银河,是旋转的 |
| ParticleMeteor | 流星,带尾巴的 |
| ParticleSmoke | 烟 |
备注
推荐粒子特效参数在线调整网站(火箭尾焰特效是通过此网站生成的一个.list 文件,然后代码中使用此文件创建相应粒子特效)
http://www.effecthub.com/particle2dx
完整代码以及资源素材见github,如果觉得不错欢迎打赏一个star
https://github.com/TopForethought/cocos2dx/tree/master/粒子特效