Cocos2d-x allows us to have particles effects in our game using its internal particle system classes.
There are two ways to create and adjust particles in your scene.
- Using Code (Which is hard to visualize the look at development time)
- Using Particle Designer or another particle design software (Effekseer, V-play particle editor, Particle2d-x)
Create Particles By Code
To create a particle emitter you need an instance of either of these classes.
- ParticleSystem
- ParticleSystemQuad
ParticleSystemQuad inherits from ParticleSystem, but also has its own unique features including:
- Particle size can be any float number.
- The system can be scaled
- The particles can be rotated
There are eleven particle preset nodes to start your particles with. These make it easy to create a particle system that looks close to what we want and then adjust them later.
- ParticleFire
- ParticleFirework
- ParticleSun
- ParticleGalaxy
- ParticleFlower
- ParticleMeteor
- ParticleSpiral
- ParticleExplosion
- ParticleSmoke
- ParticleSnow
- ParticleRain
Here is a simple example to create a particle system using these presets.
ParticleSystem* emitter = ParticleFire::create(); this->addChild(emitter);
As you see, it is basically super simple to add a particle system to your scene.
I have made a collection of the look of these particle system presets to compare.
As I mentioned, you can change the parameters of these particles in your code. We will get to that in a bit…
We can also start creating our own particle system by setting all the properties from scratch. The properties of the particle system classes let us alter the result of the presets and also define our particle system when we make our own using code.
When you are designing your own particle look, keep in mind that there are two modes to choose from. The Gravity and the Radius modes!
Gravity Mode (Mode A) properties:
- gravity
- direction
- speed +- variance
- tangential acceleration +- variance
- radial acceleration +- variance
Radius Mode (Mode B) properties:
- startRadius +- variance
- endRadius +- variance
- rotate +- variance
Properties common to all modes:
- emission rate of the particles
- life +- life variance
- start spin +- variance
- end spin +- variance
- start size +- variance
- end size +- variance
- start color +- variance
- end color +- variance
- life +- variance
- blending function
- texture
Enough talking now! Lets give this a go and create our own custom particle system from scratch. I will explain the code after.
bool ParticlesScene::init() { ////////////////////////////// // 1. super init first if ( !Scene::init() ) { return false; } auto visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); float x = origin.x + visibleSize.width * 0.5; float y = origin.y + visibleSize.height * 0.5; Image *image = new Image(); image->initWithImageFile("circle.png"); Texture2D *texture = new Texture2D(); texture->initWithImage(image); ParticleSystemQuad* emitter = ParticleSystemQuad::create(); emitter->setTexture(texture); emitter->setBlendFunc(BlendFunc::ADDITIVE); // Common Properties emitter->setPosition(x, y); emitter->setVisible(true); emitter->setEmissionRate(50.0); emitter->setDuration(ParticleSystem::DURATION_INFINITY); emitter->setLife(3.0); emitter->setLifeVar(1.0); emitter->setStartSpin(1.0); emitter->setStartSpinVar(0.2); emitter->setEndSpin(1.0); emitter->setEndSpinVar(0.2); emitter->setStartSize(10.0); emitter->setStartSizeVar(5.0); emitter->setEndSize(1.0); emitter->setEndSizeVar(0.1); emitter->setStartColor(Color4F(1.0, 1.0, 1.0, 1.0)); emitter->setStartColorVar(Color4F(1.0, 1.0, 1.0, 1.0)); emitter->setEndColor(Color4F(1.0, 1.0, 1.0, 1.0)); emitter->setEndColorVar(Color4F(1.0, 1.0, 1.0, 1.0)); // Mode: Gravity emitter->setEmitterMode(ParticleSystem::Mode::GRAVITY); emitter->setGravity(Vec2(0, 9.8)); emitter->setSpeed(10.0); emitter->setSpeedVar(2.0); emitter->setTangentialAccel(100.0); emitter->setTangentialAccelVar(50.0); emitter->setRadialAccel(20.0); emitter->setRadialAccelVar(5.0); // Mode: Radial /* emitter->setEmitterMode(ParticleSystem::Mode::RADIUS); emitter->setStartRadius(10.0); emitter->setStartRadiusVar(5.0); emitter->setEndRadius(150.0); emitter->setEndRadiusVar(20.0); emitter->setRotatePerSecond(90.0); emitter->setRotatePerSecondVar(20.0); */ this->addChild(emitter); return true; }
The first part of the code is just finding the center of the screen for our particle system position on the screen.
Then we create an Image that we feed to a Texture! That is because particle system needs to show a Texture on each particle for it to be visible.
We create an instance of the ParticleSystemQuad (or ParticleSystem) and then set its parameters. The most important ones are the texture and image blending mode.
The other properties are quite self explanatory! Things like visibility, duration, emitting rate, gravity, spin angles, start and end colors, start and end sizes, etc…
I recommend to spend some time and play with those values to see what they do and get a hang of it before moving on.
Create Particles By Using Particle Designer
Designing particle systems in code can be a bit difficult as you don’t get an instant visual feedback of how your particle looks by changing its properties. Particle Designer lets you develop a particle system in real time and save the emitter as a .plist file that you can load into Cocos2d-x. It makes creating particles easier and much more fun.
Here I have chosen a preset from the pre-made particles as an example to bring into XCode.
If you press the button that I put a red rectangle around, you will get these four pages of particle settings to change the look of your particle.
Lets say we like what we see and we don’t want to change anything. Now we can export this to use in our project.
First we select the particle layer that is called untitled, press Cmd+S to rename it and then save the project. I called it “Funky”! Set the export settings to .plist and press the big export button, specify the folder and voila!
The export will save you a Funky.plist in the Resources folder. But, you need to also copy a texture Funky.png in that folder for it to work. I just copy the circle texture from the previous custom example in here and rename it for now.
We just add it to our XCode project and write the code to load it this way:
auto visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); float x = origin.x + visibleSize.width * 0.5; float y = origin.y + visibleSize.height * 0.5; ParticleSystemQuad* emitter = ParticleSystemQuad::create("Funky.plist"); emitter->setPosition(x, y); this->addChild(emitter);