I'm using a SKEmitterNode to emit some particles on tap. I'm after an effect similar to the hearts in Periscope.
I find that when I add the emitter it doesn't behave like it was just "turned on". That is, particles appear with full alpha far from the spawn point (as if they've been alive for a while). It is as if the emitter has been running it was suddenly shown.
What I'm after is tap -> add node-> start emitting from point -> emit for a while -> shut off -> remove node.
I've tried adjusting the particleBirthRate using GCD:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if(self.burstEmitter.parent){
return;
}
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInNode:self];
self.burstEmitter.position = point;
self.burstEmitter.particleBirthRate = 0;
[self addChild:self.burstEmitter];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.burstEmitter.particleBirthRate = 10;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.burstEmitter.particleBirthRate = 0;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self removeAllChildren];
});
});
});
}
Then I though SKAction might be the right tool (it probably is...)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if(self.burstEmitter.parent){
return;
}
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInNode:self];
self.burstEmitter.position = point;
self.burstEmitter.particleBirthRate = 10;
[self addChild:self.burstEmitter];
[self.burstEmitter runAction:[SKAction sequence:@[
[SKAction fadeInWithDuration:1],
[SKAction waitForDuration:2],
[SKAction fadeOutWithDuration:1],
[SKAction removeFromParent]
]]];
}
This obviously fades the emitter node out, not "shut it off",
I'm open to using CAEmitterLayer. I tried that as well but ran into the same issue.
Update: I found one solution: resetSimulation.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if(self.burstEmitter.parent){
return;
}
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInNode:self];
self.burstEmitter.position = point;
self.burstEmitter.particleBirthRate = 10;
[self.burstEmitter resetSimulation];
[self addChild:self.burstEmitter];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.burstEmitter.particleBirthRate = 0;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self removeAllChildren];
});
});
}
This accomplishes what I was after. I'm still curious to use SKAction for this if possible.