I'm playing around with CAEmitterLayer and I face some problems now :(
I need a short particle effect - like a hit or explosion - at one place for example (so I have small UIView at this place). How should I do that?
1, I had an idea - create the emitterLayer with it's particles and set the lifeTime to 0. And when I need it I set the lifeTime to 1 for example and after awhile I can set it back to 0. - BUT it's not doing anything :(
2, The second idea was to create [CAEmitterLayer layer] every time I need it and add it as a layers sublayer. But I'm thinking what happen when I repeat it for example ten times… I have 10 sublayers with one acive and 9 "dead"? How to stop emitting in general? I have performSelector after some time to set the lifetime to 0 and other selector with longer interval to removeFromSuperlayer… But it's not so pretty as I would like to have it :( is there another "proper" way?
I think with too many sublayers is related my other problem… I want to emit just one particle. And when I do it it works. But SOMETIMES it emit three particles, sometimes two… And it makes me mad about that. When I don't stop emitter it's giving every time the correct number of particles...
So the questions…
how to emit particles for a short time. how to work with them - like stop, remove from parent layer, … how to emit just exact number of particles
EDIT:
emitter = [CAEmitterLayer layer];
emitter.emitterPosition = CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2);
emitter.emitterMode = kCAEmitterLayerPoints;
emitter.emitterShape = kCAEmitterLayerPoint;
emitter.renderMode = kCAEmitterLayerOldestFirst;
emitter.lifetime = 0;
particle = [CAEmitterCell emitterCell];
[particle setName:@"hit"];
particle.birthRate = 1;
particle.emissionLongitude = 3*M_PI_2;//270deg
particle.lifetime = 0.75;
particle.lifetimeRange = 0;
particle.velocity = 110;
particle.velocityRange = 20;
particle.emissionRange = M_PI_2;//PI/2 = 90degrees
particle.yAcceleration = 200;
particle.contents = (id) [[UIImage imageNamed:@"50"] CGImage];
particle.scale = 1.0;
particle.scaleSpeed = -0.5;
particle.alphaSpeed = -1.0;
emitter.emitterCells = [NSArray arrayWithObject:particle];
[(CAEmitterLayer *)self.view.layer addSublayer: emitter];
Then in method linked with button I do this:
emitter.lifetime = 1.0;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.9 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
emitter.lifetime = 0;
});
EDITED and UPDATED after changing to @David Rönnqvist attitude
CAEmitterCell *dustCell = [CAEmitterCell emitterCell];
[dustCell setBirthRate:1];
[dustCell setLifetime:1.5];
[dustCell setName:@"dust"];
[dustCell setContents:(id) [[UIImage imageNamed:@"smoke"] CGImage]];
[dustCell setVelocity:50];
[dustCell setEmissionRange:M_PI];
// Various configurations for the appearance...
// This is the only cell with configured scale,
// color, content, emissionLongitude, etc...
[emitter setEmitterCells:[NSArray arrayWithObject:dustCell]];
[(CAEmitterLayer *)self.view.layer addSublayer:emitter];
// After one burst, change the birth rate of the cloud to 0
// so that there is only one burst per side.
double delayInSeconds = 0.5; // One cloud will have been created by now, but not two
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[emitter setLifetime:0.0];
[emitter setValue:[NSNumber numberWithFloat:0.0]
forKeyPath:@"emitterCells.dust.birthRate"];
});
OK, finally, after hours of testing and trying very different styles (initializing, removing, configuring emitters) I came up with the final result... And actually it makes me very upset...
---It is not possible!---
Even when I create emitter and its particles everytime I need it, if I set only one particle to emit, it gives me most of time one particle... BUT it is not 100% and sometimes it just emitts three particles, or two... It's random. And that is very bad. Because it is visual effect... :(
Either way if someone has a tip how to solve this, please let me know...