让我们创建一个基本精灵和一个发射器,并让发射器成为精灵的孩子,以便它跟随它:
let sprite = SKSpriteNode(color: .white, size: CGSize(width: 20, height: 10))
let emitter = SKEmitterNode() // better to use the visual designer in Xcode...
emitter.particleLifetime = 1.0
emitter.particleBirthRate = 50.0
emitter.particleSpeed = 100.0
emitter.emissionAngleRange = .pi / 5
emitter.particleTexture = SKTexture(imageNamed: "spark")
emitter.particleScale = 0.1
emitter.particleAlphaSpeed = -1.0
emitter.emissionAngle = -.pi
sprite.addChild(emitter) // attach it to the sprite
emitter.position.x = -15 // but not to the center
scene.addChild(sprite)
sprite.run(SKAction.group([ // let's run some actions to test it:
SKAction.sequence([
SKAction.move(to: CGPoint(x: 200, y: 200), duration: 5),
SKAction.move(to: CGPoint(x: 50, y: 50), duration: 5),
]),
SKAction.rotate(byAngle: .pi * 2.0, duration: 10)
]))
(如果显示不正确,请点击打开 GIF 动画:)
对于不经意的观察者来说,它看起来不错……除了经过一番仔细检查后,您会发现有什么不对劲:发射的粒子生活在父精灵的宇宙中,随着它移动和旋转,即使在它们发射很久之后也是如此!这是不对的!
那是因为发射器的targetNode是它的父级,应该是场景!
所以让我们在某处插入这一行:
emitter.targetNode = scene // otherwise the particles would keep moving with the sprite
(如果显示不正确,请点击打开 GIF 动画:)
好的,这是不行的:粒子现在停留在场景的“宇宙”中,但显然它们的发射角度不符合父级的发射角度(这在我看来像是一个错误)。
幸运的是,我们可以将自定义动作附加到发射器,它会保持这个角度与父精灵对齐:
emitter.run(SKAction.repeatForever(
SKAction.customAction(withDuration: 1) {
($0 as! SKEmitterNode).emissionAngle = sprite.zRotation + .pi
_ = $1
}))
(如果显示不正确,请点击打开 GIF 动画:)
好的,现在新粒子以正确的方向发射,并且即使精灵在此期间移动或旋转,也会继续以该方向移动。这似乎是迄今为止最真实的模拟,尽管仍有办法通过动态修改发射器的行为来改进它。
对于锯齿状的 GIF 感到抱歉,显然我的 Mac 太慢了,无法同时渲染和捕捉。动画本身运行良好。