SKSpriteNode 在 Timer 到期时 removeFromParent() 后不会消失

SKSpriteNode doesn't disappear after removeFromParent() when Timer expires

在我的游戏中,我希望每次我的玩家触摸一个物体时,屏幕都会变白约 0.5 秒,然后恢复正常。

我的代码是:

private var crash: SKSpriteNode?

func crashadd(){
    crash = SKSpriteNode(imageNamed: "Gameplay BG")
    crash?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    crash?.position.x = 0
    crash?.position.y = 0
    crash?.zPosition = 15
    mainCamera?.addChild(crash!)

    Timer.scheduledTimer(timeInterval: TimeInterval(0.1), target: self, selector: #selector(GameplayScene.removeCrash), userInfo: nil, repeats: false)
}

func removeCrash() {
    crash?.removeFromParent()
}

问题是 crash 节点有时不会自行删除。

您可能在计时器到期前第二次调用 crashadd()。如果这样做,它将覆盖对第一个 crash 的引用,但不会将其从屏幕上删除。当第一个计时器到期时,它将删除当前引用(第二个 crash)。当第二个计时器到期时,它将尝试删除相同的 crash 并默默地失败。第一个 crash 永远不会被删除。

要解决此问题,您可以进行检查以确保屏幕上还没有 crash。在 crashadd() 的顶部添加:

guard crash == nil else {
    return
}

现在它将检查 crash 是否为空。如果不是,函数 returns 什么也不做(因为屏幕上已经出现崩溃)。

由于崩溃可能会发生多次,您还应该添加

crash = nil

removeCrash() 结束时清除它以备下次使用。


重要提示

您可能还应该查看多次调用 crashadd() 的位置,然后确定该行为是否是您真正想要的。

如果玩家连续触摸一个物体,您的代码可能会在每一帧调用 crashadd() 并在旧的 crash 过期后立即抛出一个新的 crash ,看起来它是从未删除。您需要确保每次碰撞只调用一次碰撞函数,而不是在碰撞持续时重复调用。