Reputation: 387
I created a SKEmitterNode and I want the particleTexture property to animate images.
This is what I'm trying, but it is only showing the first image:
let animationImages = [UIImage(named: "image1")!, UIImage(named: "image2")!]
let imageView = UIImageView()
imageView.image = UIImage.animatedImage(with: animationImages, duration: 1)
imageView.startAnimating()
emitter.particleTexture = SKTexture(image: imageView.image!)
Upvotes: 1
Views: 271
Reputation: 6255
let image1 = SKAction.run( { emitter.particleTexture = SKTexture(imageNamed: "image1") } )
let image2 = SKAction.run( { emitter.particleTexture = SKTexture(imageNamed: "image2") } )
let image3 = SKAction.run( { emitter.particleTexture = SKTexture(imageNamed: "image3") } )
let seq = SKAction.sequence([image1, wait, image2, wait, image3, wait])
let repeater = SKAction.repeatForever(seq)
emitter.run(repeater)
Upvotes: 1
Reputation: 336
Your last line will always return the same "main" image, regardless of the animation. This was confirmed elsewhere on this site already, but see also Apple's documentation of UIImageView.image
.
But even if you did manage to obtain the current image, it would still be a one-time assignment, and the texture wouldn't update automatically; that's something you will need to do yourself; as Apple puts it in Animating a Sprite by Changing its Texture in Apple's SpriteKit
reference:
A sprite’s texture property points to its current texture. You can change this property to point to a new texture.
Luckily, there's an SKAction
to do just that (see the last link for some details), and it can theoretically even be applied to SKEmitterNode
particles (something I just found out as I was about to tell you the opposite):
let animationTextures = [SKTexture(imageNamed: "image1"),
SKTexture(imageNamed: "image2"),
SKTexture(imageNamed: "image3")]
let animationAction = SKAction.repeatForever(SKAction.animate(with: textures, timePerFrame: 0.1))
emitter.particleAction = animationAction
EDIT: It doesn't work, and hasn't worked for years: particleAction
s are simply being ignored. It's quite incredible that Apple wouldn't fix such an obvious bug for half a decade, but this seems to be the case.
SKEmitterNode
s have a lot going for them (this bug notwithstanding):
SKSpriteNode
-like thingies that are optimized for being thrown around in huge numbers without all the overhead associated with full-blown sprite nodes.However, I already found myself in a situation once where I was forced to implement my own "emitter." In my case, it involved little more than writing a method creating a fixed number of sprite nodes, and attaching a complex action (three levels of hierarchy of multiple groups and sequences) to each of them that controlled their movement, scale, alpha, and eventual disappearance (removal from parent). It was not a huge amount of work, and it gave me the precise control I needed over the particle animations that an emitter node couldn't provide – but I was lucky in that I only needed to emit a few dozen particles at a time.
I'd say implementing your own emitter would make the most sense if all of the following conditions are true:
SKEmitterNode
doesn't provide; andSKEmitterNode
in Xcode, and re-use the parameters of your prototype in your final implementation; andSKEmitterNode
, which may not be a trivial task.Once again, good luck: SpriteKit
could be a fantastic framework if only Apple got around to fixing some of its pretty outrageous bugs. (I'm having issues with custom shaders… Maybe you will see a question or two from me in the near future.)
Upvotes: 2