Duplicating a Particle Emitter Effect in Sprite Kit

Sprite Kit Particle Emitter Shape

Only a SKTexture can be used, but that doesn't stop you from using SKShapeNode to create shapes and then create a SKTexture of that shape via the SKView method textureFromNode:.

How do I create a blinking effect with SKEmitterNode?

I don't think you can do much directly in the editor. If you're comfortable working with code for adjusting the emitter, you have a couple of possibilities: setting a particle action to animate color or alpha or scale or texture, or a custom shader to do whatever sort of animation. (I'm assuming based on your picture with a basically infinite lifetime that you don't want things to move or disappear. That may rule out keyframing, but perhaps having the keyframe sequence set to repeat mode with the frames spaced by really tiny values would work.)

Another possibility since positions are static would be to just make some fixed sprites scattered around at random and have them run actions to animate them. We've used this approach before with ~100 animated sprites against a backdrop that has a bunch of dimmer stars, and it looked pretty good. Something along these lines:

let twinklePeriod = 8.0
let twinkleDuration = 0.5
let bright = CGFloat(0.3)
let dim = CGFloat(0.1)
let brighten = SKAction.fadeAlpha(to: bright, duration: 0.5 * twinkleDuration)
brighten.timingMode = .easeIn
let fade = SKAction.fadeAlpha(to: dim, duration: 0.5 * twinkleDuration)
fade.timingMode = .easeOut
let twinkle = SKAction.repeatForever(.sequence([brighten, fade, .wait(forDuration: twinklePeriod - twinkleDuration)]))
for _ in 0 ..< 100 {
let star = SKSpriteNode(imageNamed: "star")
star.position = CGPoint(x: .random(in: minX ... maxX), y: .random(in: minY ... maxY))
star.alpha = dim
star.speed = .random(in: 0.5 ... 1.5)
star.run(.sequence([.wait(forDuration: .random(in: 0 ... twinklePeriod)), twinkle]))
addChild(star)
}

That's cut-and-pasted from various bits and simplified some, so there may be typos, but it should give the idea. If you keep the emitter, you can try something like the twinkle above as the particle action. I don't see how you can change the relative periods of particles though like you could with separate sprites, and the only offsets would come from differences in the birth time of the particles.

Swift and Sprite Kit - unarchiving a particle emitter (sks) file

Try unwrapping the filePath:

_bloodEmitter = NSKeyedUnarchiver.unarchiveObjectWithFile(NSBundle.mainBundle().pathForResource("Blood", ofType: "sks")!)

iOS SpriteKit Emitter particle frequency

I stay away from timers, there really isn't a need for them in SpriteKit

You have a built in timer function with the update func, or you can Just use actions to control your time.

what you are probably looking for is particle.resetSimulation()

I would do what you need to do like so

you can also put a key on your action and stop it by key name whenever needed

if let spark = self.childNode(withName: "sparkin") as? SKEmitterNode {

self.spark = spark

//set time here to how long in between restarting the emitter
let waiter = SKAction.wait(forDuration: 5)
let resetter = SKAction.run( { self.spark.resetSimulation() } )
let seq = SKAction.sequence([waiter, resetter])
let repeater = SKAction.repeatForever(seq)
run(repeater)
}

SpriteKit particle emitter change color

This hardly counts as an answer but I couldn't fit it all into a comment so...please bear with me.

The good news is that your code seems to work!

I tried creating a new Sprite Kit project and pasted your code into that so I ended up with a GameScene class of type SKScene looking like this:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

let emitter = SKEmitterNode(fileNamed: "squares.sks")
let colors = [SKColor.red, SKColor.green, SKColor.blue]
var lastUpdateTime: TimeInterval?

override func didMove(to view: SKView) {
emitter?.particleColorBlendFactor = 1.0
emitter?.particleColorSequence = nil
addChild(emitter!)
}

override func update(_ currentTime: TimeInterval) {
var delta = TimeInterval()
if let last = lastUpdateTime {
delta = currentTime - last
} else {
delta = currentTime
}
if delta > 1.0 {
lastUpdateTime = currentTime
let random = Int(arc4random_uniform(UInt32(self.colors.count)))
emitter?.particleColor = colors[random]
}
}
}

And then I created a new SKEmitterNode from the template (I used fire...just to chose something) and named it squares.sks.

When I run that, I can see this:

Sample Image

So...where does that leave us?

I'm thinking there must be something different in your setup.
If you try to create a new example project like mine, are you able to get it to work?

Yeah...hardly an answer I know, but think of it as a reassurance that you are on the right path at least :)



Related Topics



Leave a reply



Submit