无法在 iOS9 中重复使用具有不同父级的发射器节点
Can't re-use emitter node with different parent in iOS9
我正在尝试汇集我的粒子发射器节点。我在需要时重新使用它们,方法是将它们从旧的父节点中移除,并将它们添加为新位置的 SKSpriteNode 的子节点。我将发射器节点位置设置为 0,0,因此发射器应该出现在其新父精灵节点的中心。
发射器在第一次作为子节点添加到精灵节点时正确显示,但在后续尝试中根本不显示。这一切在 iOS8 中运行良好,仅在 iOS9 中被破坏(在 iOS9 中似乎有很多粒子发射器错误?)
这是我需要放置粒子效果时的基本代码示例:
if emitter.parent != nil {
emitter.removeFromParent()
}
newLocationSpriteNode.addChild(emitter)
emitter.resetSimulation()
这在 iOS8 中非常有效 - 我可以在新位置重新使用我的发射器节点。在 iOS9 中,节点仅在该代码第一次运行时出现,之后再也不会出现。您对我如何解决此问题有任何见解吗?谢谢!
我遇到了与您描述的完全相同的问题。第二次重新连接时,发射器不可见。不过在 ios8 上一切正常。在尝试了几个小时的不同设置后,我几乎要放弃了。但是,我找到了一个现在可行的解决方案。首先,我有一个 SKEmitterNodes 池,我在游戏过程中会重复使用这些节点。此方法从池(数组)中获取一个发射器并将其添加到游戏层(SKNode):
func createExplosion(position: CGPoint) {
let emitter = _pool.borrowDirtEmitter()
emitter.resetSimulation() //Important
emitter.position = position
emitter.targetNode = self //Important
if emitter.parent == nil {
self.addChild(emitter)
}
}
所以 "self" 这是我将发射器附加到的实际节点。当节点在屏幕外时,我清理发射器(和其他对象):
if let dirtEmitter = childNode as? SKEmitterNode {
if dirtEmitter.parent != nil {
dirtEmitter.removeFromParent()
}
dirtEmitter.targetNode = nil //Important!
_pool.returnDirtEmitter(dirtEmitter)
}
我还没有时间进行更详细的介绍,但是 "Important" 评论应该会给您一些指导。我将尝试测试一种方法,也使用从父对象中删除的操作(x 秒后),但由于我正在制作侧滚动条,所以我现在可以在发射器不在屏幕上时进行清理。
希望这对您有所帮助..
我正在尝试汇集我的粒子发射器节点。我在需要时重新使用它们,方法是将它们从旧的父节点中移除,并将它们添加为新位置的 SKSpriteNode 的子节点。我将发射器节点位置设置为 0,0,因此发射器应该出现在其新父精灵节点的中心。
发射器在第一次作为子节点添加到精灵节点时正确显示,但在后续尝试中根本不显示。这一切在 iOS8 中运行良好,仅在 iOS9 中被破坏(在 iOS9 中似乎有很多粒子发射器错误?)
这是我需要放置粒子效果时的基本代码示例:
if emitter.parent != nil {
emitter.removeFromParent()
}
newLocationSpriteNode.addChild(emitter)
emitter.resetSimulation()
这在 iOS8 中非常有效 - 我可以在新位置重新使用我的发射器节点。在 iOS9 中,节点仅在该代码第一次运行时出现,之后再也不会出现。您对我如何解决此问题有任何见解吗?谢谢!
我遇到了与您描述的完全相同的问题。第二次重新连接时,发射器不可见。不过在 ios8 上一切正常。在尝试了几个小时的不同设置后,我几乎要放弃了。但是,我找到了一个现在可行的解决方案。首先,我有一个 SKEmitterNodes 池,我在游戏过程中会重复使用这些节点。此方法从池(数组)中获取一个发射器并将其添加到游戏层(SKNode):
func createExplosion(position: CGPoint) {
let emitter = _pool.borrowDirtEmitter()
emitter.resetSimulation() //Important
emitter.position = position
emitter.targetNode = self //Important
if emitter.parent == nil {
self.addChild(emitter)
}
}
所以 "self" 这是我将发射器附加到的实际节点。当节点在屏幕外时,我清理发射器(和其他对象):
if let dirtEmitter = childNode as? SKEmitterNode {
if dirtEmitter.parent != nil {
dirtEmitter.removeFromParent()
}
dirtEmitter.targetNode = nil //Important!
_pool.returnDirtEmitter(dirtEmitter)
}
我还没有时间进行更详细的介绍,但是 "Important" 评论应该会给您一些指导。我将尝试测试一种方法,也使用从父对象中删除的操作(x 秒后),但由于我正在制作侧滚动条,所以我现在可以在发射器不在屏幕上时进行清理。
希望这对您有所帮助..