Reputation: 10738
I'm currently practicing with particle systems and I was wondering if the following code is the right way to stop and start a particle when a button is tapped?
The code works fine, I touch the start button and the particle starts, I touch the stop button and the particle stops but I'm not sure if removeFromSuperLayer
is the right method to use. As I said, the code does what I need but I just want to make sure that the particle won't keep running in the background even after calling removeFromSuperLayer
and end-up wasting resources.
- (IBAction)stopAnimation:(id)sender
{
[emitterLayer removeFromSuperlayer];
}
- (IBAction)startAnimation:(id)sender
{
[self particle];
}
-(void) particle
{
emitterLayer = [CAEmitterLayer layer];
emitterLayer.emitterPosition = CGPointMake(50 ,50);
emitterLayer.emitterZPosition = 10;
emitterLayer.emitterSize = CGSizeMake(10,10);
emitterLayer.emitterShape = kCAEmitterLayerSphere;
CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];
emitterCell.scale = 0.1;
emitterCell.scaleRange = 0.2;
emitterCell.emissionRange = (CGFloat)M_PI_2;
emitterCell.lifetime = 10;
emitterCell.birthRate = 5;
emitterCell.velocity = 20;
emitterCell.velocityRange = 50;
emitterCell.yAcceleration = 0;
emitterCell.contents = (id)[[UIImage imageNamed:@"particleImage.png"] CGImage];
emitterLayer.emitterCells = [NSArray arrayWithObject:emitterCell];
[self.view.layer addSublayer:emitterLayer];
}
Thanks a lot
Upvotes: 7
Views: 3457
Reputation: 11993
Rather than change the birthRate of the each of the emitterCells you can change the birthrate of the emitterLayer itself.
- (void)stopEmitting
{
self.emitterLayer.birthRate = 0;
}
- (void)startEmitting
{
self.emitterLayer.birthRate = 1;
}
Upvotes: 4
Reputation: 10738
It's funny but just modifying the birthRate like this self.emitterCell.birthRate = 0.0f;
in a method doesn't stop the emitterCell, in fact it looks like if it appends instead of stopping it, in other words if I change it to self.emitterCell.birthRate = 100;
it adds 100 more particles to the existing particles. Lucky I found the solution.
I basically had to give my emitterCell a name emitterCell.name = @"_myCell";
and then in my stop method modify it like this [emitterLayer setValue:[NSNumber numberWithInteger:0] forKeyPath:@"emitterCells._myCell.birthRate"];
and it worked.
This is what I did that worked. This is assuming you already have an image in your project named myImage.
#import "SpriteViewController.h"
@implementation SpriteViewController
CAEmitterLayer *emitterLayer;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)stopAnimation:(id)sender
{
[emitterLayer setValue:[NSNumber numberWithInteger:0] forKeyPath:@"emitterCells._myCell.birthRate"]; // new code
}
- (IBAction)startAnimation:(id)sender
{
[self particle];
}
-(void) particle
{
emitterLayer = [CAEmitterLayer layer];
emitterLayer.emitterPosition = CGPointMake(50 ,50);
emitterLayer.emitterZPosition = 10;
emitterLayer.emitterSize = CGSizeMake(10,10);
emitterLayer.emitterShape = kCAEmitterLayerSphere;
CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];
emitterCell.name = @"_myCell";// new code
emitterCell.scale = 0.1;
emitterCell.scaleRange = 0.2;
emitterCell.emissionRange = (CGFloat)M_PI_2;
emitterCell.lifetime = 10;
emitterCell.birthRate = 5;
emitterCell.velocity = 20;
emitterCell.velocityRange = 50;
emitterCell.yAcceleration = 0;
emitterCell.contents = (id)[[UIImage imageNamed:@"myImage.png"] CGImage];
emitterLayer.emitterCells = [NSArray arrayWithObject:emitterCell];
[self.view.layer addSublayer:emitterLayer];
}
@end
Upvotes: 3
Reputation: 16292
You could use a method in which you put the following:
- (void)stopEmitting
{
self.emitterCell.birthRate = 0.0f;
}
With this you should be able to stop the emitting, without having to remove and re-create the layer each time when the start button is pressed.
To start again, simply do:
- (void)startEmitting
{
self.emitterCell.birthRate = <VAlUE HERE (greater than 0)>;
}
Hope this helps.
Upvotes: 6