设置 SKEmitterNode 的 'targetNode' 会导致奇怪的 'zPosition' 行为
Setting SKEmitterNode's 'targetNode' causes strange 'zPosition' behavior
在我的一款 SpriteKit 游戏中尝试实现 粒子轨迹 效果时,我遇到了一些奇怪的事情:设置 SKEmitterNode
时targetNode
到 self.scene
,粒子不再可见。
实际发生的事情是这样的:粒子正在渲染 a) 在 前面,或 b) 在[=42= 后面] 背景图片 SKSpriteNode
取决于是否设置 targetNode
。您可以通过为背景节点提供一些 alpha 透明度来亲眼看到这一点,这样您就可以通过 通过 背景看到粒子。
在发射器节点及其父节点上设置相关的 zPosition
并不能解决问题——无论 zPosition
是什么,粒子都在背景节点后面渲染(假设背景节点的 zPosition
已设置)。
我已将其精简为可重现的最小示例;如果你把这个 GameScene
插入一个新的 SpriteKit 项目,你应该看到我正在谈论的行为。
对于背景图片,使用任何不透明的图片即可。对于粒子文件,只需使用标准的“烟雾”模板即可。
注意:粒子在模拟器上正确渲染,因此请使用真实设备。
class GameScene: SKScene {
override func didMove(to view: SKView) {
let screen = UIScreen.main.bounds
self.scene?.backgroundColor = .white
self.scaleMode = .resizeFill
self.anchorPoint = CGPoint(x: 0.0, y: 0.0)
let background = SKSpriteNode(imageNamed: "testBackground")
let parent = SKSpriteNode()
let emitter = SKEmitterNode(fileNamed: "SmokeParticles")
background.size = CGSize(width: screen.width, height: screen.height)
background.position = CGPoint(x: screen.width*0.5, y: screen.height*0.5)
background.zPosition = 0.5 //Giving the background a zPosition is necessary to reproduce the problem.
//background.alpha = 0.7 //Add this line to see that the particles are BEHIND the background when 'targetNode' is set.
parent.size = CGSize(width: 50.0, height: 50.0)
parent.position = background.position
parent.zPosition = 5.0
if let emitter = emitter {
emitter.zPosition = 5.0 //I would think this should solve the problem, but it doesn't
emitter.targetNode = self.scene //Comment or uncomment this line to toggle the problem on/off.
parent.addChild(emitter)
}
addChild(background)
addChild(parent)
}
func touchDown(atPoint pos: CGPoint) {
}
func touchMoved(toPoint pos : CGPoint) {
}
func touchUp(atPoint pos : CGPoint) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}
override func update(_ currentTime: TimeInterval) {
}
}
问题:这是一个错误,还是一些被遗弃的功能?您是否看到了同样的行为?
我最终使用 SKEmitterNode
的 particleZPosition
属性.
解决了这个问题
在我的一款 SpriteKit 游戏中尝试实现 粒子轨迹 效果时,我遇到了一些奇怪的事情:设置 SKEmitterNode
时targetNode
到 self.scene
,粒子不再可见。
实际发生的事情是这样的:粒子正在渲染 a) 在 前面,或 b) 在[=42= 后面] 背景图片 SKSpriteNode
取决于是否设置 targetNode
。您可以通过为背景节点提供一些 alpha 透明度来亲眼看到这一点,这样您就可以通过 通过 背景看到粒子。
在发射器节点及其父节点上设置相关的 zPosition
并不能解决问题——无论 zPosition
是什么,粒子都在背景节点后面渲染(假设背景节点的 zPosition
已设置)。
我已将其精简为可重现的最小示例;如果你把这个 GameScene
插入一个新的 SpriteKit 项目,你应该看到我正在谈论的行为。
对于背景图片,使用任何不透明的图片即可。对于粒子文件,只需使用标准的“烟雾”模板即可。
注意:粒子在模拟器上正确渲染,因此请使用真实设备。
class GameScene: SKScene {
override func didMove(to view: SKView) {
let screen = UIScreen.main.bounds
self.scene?.backgroundColor = .white
self.scaleMode = .resizeFill
self.anchorPoint = CGPoint(x: 0.0, y: 0.0)
let background = SKSpriteNode(imageNamed: "testBackground")
let parent = SKSpriteNode()
let emitter = SKEmitterNode(fileNamed: "SmokeParticles")
background.size = CGSize(width: screen.width, height: screen.height)
background.position = CGPoint(x: screen.width*0.5, y: screen.height*0.5)
background.zPosition = 0.5 //Giving the background a zPosition is necessary to reproduce the problem.
//background.alpha = 0.7 //Add this line to see that the particles are BEHIND the background when 'targetNode' is set.
parent.size = CGSize(width: 50.0, height: 50.0)
parent.position = background.position
parent.zPosition = 5.0
if let emitter = emitter {
emitter.zPosition = 5.0 //I would think this should solve the problem, but it doesn't
emitter.targetNode = self.scene //Comment or uncomment this line to toggle the problem on/off.
parent.addChild(emitter)
}
addChild(background)
addChild(parent)
}
func touchDown(atPoint pos: CGPoint) {
}
func touchMoved(toPoint pos : CGPoint) {
}
func touchUp(atPoint pos : CGPoint) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}
override func update(_ currentTime: TimeInterval) {
}
}
问题:这是一个错误,还是一些被遗弃的功能?您是否看到了同样的行为?
我最终使用 SKEmitterNode
的 particleZPosition
属性.