1

我创建了一个 SKEmitterNode 以在他死后附加到我的玩家身上。这是一种非常简单的烟雾。问题是,当我要么:

1)点击重试按钮并转换到相同的场景,它会随机地导致游戏崩溃并出现 EXC_BAD_ACCESS 错误。

2) 返回主屏幕并在至少死亡一次并创建发射器节点后点击播放并转换到该游戏场景。

目前 SKEmitterNode 是一个可选的类变量。当玩家死亡时,他们设置 SKEmitterNode 并将其附加到场景中。

    // Add death smoke
    let smokePath: String = NSBundle.mainBundle().pathForResource("playerDeathSmoke", ofType: "sks")!
    self.deathSmokeEmitter = NSKeyedUnarchiver.unarchiveObjectWithFile(smokePath) as? SKEmitterNode
    self.deathSmokeEmitter?.name = "deathSmokeEmitter"
    if let deathEmitter = self.deathSmokeEmitter {
        deathEmitter.targetNode = self.scene
        self.addChild(deathEmitter)
    }

“self.addChild(deathEmitter)”将在您重新加载场景后导致崩溃(确实会出现烟雾)。这与 SKEmitterNode 文档中的示例代码添加发射器节点的方式相同。

我还尝试了各种方法来修复它,比如在播放器精灵上覆盖 removeFromParent 方法并在转换场景之前自己在其上运行“removeFromParent”。

    override func removeFromParent() {
         self.deathSmokeEmitter?.removeFromParent()
         //self.deathSmokeEmitter?.targetNode = nil

         super.removeFromParent()
     }

完成此操作后,只有在先返回主屏幕然后转换回游戏场景时才会发生崩溃。这意味着如果将其注释掉,我可以多次快速重试,但如果我回到主场景并返回游戏场景,它仍然会崩溃。此外,当它以这种方式崩溃时,堆栈跟踪会显示崩溃前的最后一个方法:

 [SKEffectNode dealloc]

如果您有任何想法,请告诉我,谢谢!

PS:我在过渡期间没有做任何奇怪的事情。我只是实例化一个过渡并推动下一个场景。我依靠 SpriteKit 为我完成所有的清洁工作。

4

1 回答 1

1

所以我发现了如何解决这个问题(当我问这个问题时,我几乎已经弄清楚了),但为了澄清,我把它打出来。

出于某种原因,iOS 8 中的 SpriteKit 在切换场景时不会从 Player sprite 中移除烟雾发射器。这会以某种方式导致崩溃,因为它出于某种原因试图在下一个场景中对其执行一些逻辑。

我上面所说的几乎是正确的。首先使用粒子发射器子对象的 removeFromParent() 方法覆盖精灵,如下所示

// Sprite with ParticleEmitterNode child attached to it's method
override func removeFromParent() {
     self.deathSmokeEmitter?.removeFromParent()

     super.removeFromParent()
 }

在切换场景之前,只需执行 spriteWithEmitterChild.removeFromParent() 从场景中移除精灵(将发射器作为子对象),这将调用重写方法并在从场景中移除精灵之前从精灵中移除烟雾发射器。

于 2015-06-30T17:37:53.233 回答