0

In my SK game, I have a helicopter that launches rockets. The heli can only have one rocket on the screen at a time, the reason being that I didn't want to have to create a new SKEmitterNode every time a rocket is launched, because it seems this would be taxing on the CPU, having to unarchive the emitter every time.

Therefore, the rocket is a single instance. When someone launches a rocket, it is added to the scene as a child of the scene, launched, and when it hits something, removed from it's parent.

In my update{} metho, here's some psuedo-code:

if ([rocket parent]) {
     rocketSmoke.position = rocket.position;
     rocketSmoke.numParticlesToEmit = 0;
}else{
     rocketSmoke.numParticlesToEmit = 1;
}

So basically, the emitter follows the rocket if it exists and if it doesn't exist, the emitter turns itself off. No, I cannot just add the emitter as a child of the rocket because then when the rocket hits an object and I call removeFromParent the smoke trail behind the rocket will instantly dissapear and that's not the effect I'm going for.

The problem is, when a new rocket is launched and numParticlesToEmit is set back to zero, the particle emitter acts like it's been emitting particles the entire time! I want the particle emitter to simply turn back on, but a bunch of smoke instantaneously appears behind the helicopter as well. You can observe this effect by playing with an emitter file in SK and setting the "max" on the particles to emit to 1, and then setting it back to zero: your screen will instantaneously fill back up as if it had been emitting particles the whole time. Obviously that's not what I want.

I also can't call resetSimulation, because that will remove all existing particles, and so any lingering smoke from the last launch will instantaneously disappear, which would look pretty unnatural if two rockets were launched one after another.

Is my only option to write my own emitter?

Todd
  • 143
  • 8

1 Answers1

0

Create new instances of the emitter for each different rocket. That will resolve your problem.

If it becomes "Too Taxing on the CPU" then create two emitters and alternate which one is used.

Ex. Fire rocket 1, use emitter 1.
Fire rocket 2, use emitter 2.
Fire rocket 3, use emitter 1.

This will give you time for the emitter to finish the effect you want when a rocket hits something while also allowing your next rocket's emitter to behave as desired.

meisenman
  • 1,818
  • 1
  • 15
  • 25
  • but if I am creating new instances of the emitter for each rocket, then when the rocket hits something, how do I tell that specific emitter to wait for a few seconds before destroying itself? – Todd Oct 13 '14 at 17:12
  • Subclass SKSpriteNode as RocketSpriteNode and add a property named emitterArrayIndex. Put the emitters in an array. When you create the rocket, assign the rockets emitterArrayIndex property to equal the respective emitters array index. When your rocket contacts something, you can access the emitter by finding the emitter at array index = rocket.emitterArrayIndex. (rocket being the one that hit something) – meisenman Oct 13 '14 at 17:36
  • still, once the rocket hits something and I call 'removeFromParent', the emitter will be removed from it's parent as well. Therefore the smoke trail will disappear. Perhaps I am in need of a new question for this. – Todd Oct 13 '14 at 19:37
  • Once it hits something, you need to make a sequence of runActions to delay and then remove. The first runAction could be something like [SKAction ScaleBy: 0 duration:5] which would pause for 5 seconds. Then a second SKAction that uses runBlock to remove the emitter. Therefore, on contact you call that sequence which will delay for 5 seconds and then remove you emitter. This runs essentially on another thread so it will not hang up your game at all after contact. – meisenman Oct 13 '14 at 23:01