Let’s talk today about particle systems… particle, what? Yes, you’ve heard it right. You’ve probably seen it already in many iOS apps, particularly in game applications. I think this is a really cool Core Animation tool you can use in your projects.
Apple introduced with iOS 5 an entire family of specialized layers, subclasses of the
CATransformLayer. Each of those classes has been designed for a very specific task.
Before moving forward, I recommend that you introduce yourself to the basic concepts of Core Animation taking a look at the following posts we wrote in the past:
- Part I: Warm Up
- Part II: Layers Everywhere
- Part III: Basic Animations
- Part IV: Grouping Animations
- Part V: Keyframe Animations
- Part VI: Replicator Layers
- Replicator Layers
- Transform Layers
If you want to know more about Core Animation, I suggest you to check our iOS training classes.
The concept of particle systems
We are going to dive today into the
CAEmitterLayer class, which is the class that provides a particle emitter system in Core Animation.
Let’s start reviewing the main concepts. The term particle system is defined in computer graphics. A particle system is composed of a large number of small graphic objects that work together to simulate different group dynamics, like fire, smoke, fog, snow, rain, explosions, meteor tails,…
There are two classes that you need to use in order to create a particle systems:
CAEmitterLayer acts as the particle emitter (the source of the particles) and the
CAEmitterCell represents the particle being emitted.
Let’s build a project
Let’s put all the theory in practice with a very simple example. Launch Xcode and create a new Single-View Application iPhone project. Name it ParticleEmitter. Add the QuartzCore framework to the project and in the ViewController.h add:
Now, go the ViewController.m and edit the
viewDidLoad method as follows:
CAEmitterLayer *emitterLayer = [CAEmitterLayer layer]; // 1
emitterLayer.emitterPosition = CGPointMake(self.view.bounds.size.width / 2, self.view.bounds.origin.y); // 2
emitterLayer.emitterZPosition = 10; // 3
emitterLayer.emitterSize = CGSizeMake(self.view.bounds.size.width, 0); // 4
emitterLayer.emitterShape = kCAEmitterLayerSphere; // 5
Line 1 creates a particle emitter system, line 2 and 3 specifies the position where the layer will be, line 4 specifies the size of the particle emitter shape and line 5 specifies the emitter shape. If you check the
CAEmitterLayer in the documentation you will learn about different geometries you can set for the emitter layer. In our example, I chose a sphere and I set the position accordingly, but if you choose a shape point. you will have to set only its position.
Now, that we have the particle emitter, let’s create the particles. First of all, we need an image of what our particle will be. I created a simple colored ball and I imported my .png file to the project.
Now, let’s go back to the
viewDidLoad method and add the following lines of code:
CAEmitterCell *emitterCell = [CAEmitterCell emitterCell]; // 6
emitterCell.scale = 0.1; // 7
emitterCell.scaleRange = 0.2; // 8
emitterCell.emissionRange = (CGFloat)M_PI_2; // 9
emitterCell.lifetime = 5.0; // 10
emitterCell.birthRate = 10; // 11
emitterCell.velocity = 200; // 12
emitterCell.velocityRange = 50; // 13
emitterCell.yAcceleration = 250; // 14
Line 6 creates the emitter cell. Line 7 specifies the scale factor applied to the cell and line 8 the range over which the scale value can vary during the animation (the system controls that). Line 9 sets the angle defining a cone around the emission angle. From line 10 to 14 we set different emitter cell temporal attributes like the lifetime of the cell (in seconds), the birth rate (the number of emitted objects created every second), the initial velocity of the cell, the velocity range (the amount by which the velocity of a cell can vary) and the y component of the acceleration vector applied to the cell.
Let’ now provide the cell content:
emitterCell.contents = (id)[[UIImage imageNamed:@"WaterDrop.png"] CGImage]; // 15
and finally, let’s add the emitter cell to the emitter layer:
self.emitterLayer.emitterCells = [NSArray arrayWithObject:emitterCell]; // 16
The last thing we need to do is to add the emitter layer to our view’s layer, so that all the work we’ve done is actually visible. To do that, add the following line of code:
[self.view.layer addSublayer:emitterLayer]; // 17
Now, just build and run and you should see the following result:
Very cool, right? I encourage you to play with the properties we used in our small example and check the documentation where you will find other properties you could use. I am attaching here an example. There, I added 2 emitter cells to get more cell types.
I hope you enjoyed this post,