当弹丸击中两个“怪兽”时, didBeginContact方法崩溃。我知道为什么,但我不知道如何避免 [英] When projectile hits two "monsters" the didBeginContact method crashes. I know why but i don't know how to avoid it

查看:139
本文介绍了当弹丸击中两个“怪兽”时, didBeginContact方法崩溃。我知道为什么,但我不知道如何避免的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我从教程中获得了这段代码:

So I have this code from the tutorial:

func didBeginContact(contact: SKPhysicsContact) {

    // 1
    var firstBody: SKPhysicsBody?
    var secondBody: SKPhysicsBody?
    var body: SKPhysicsBody

    //contact.bodyB.node!.physicsBody!.allContactedBodies().count


        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
            println("1 = A, 2 = B")
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
            println("2 = A, 1 = B")
        }



        // 2
        if ((firstBody!.categoryBitMask & PhysicsCategory.Monster != 0) &&
            (secondBody!.categoryBitMask & PhysicsCategory.Projectile != 0)) {

                for var c = 1; c <= contact.bodyB.node!.physicsBody!.allContactedBodies().count; c++ {
                    projectileDidCollideWithMonster(firstBody!.node as! SKSpriteNode, monster: secondBody!.node as! SKSpriteNode)

                }
                secondBody!.node?.removeFromParent()
        }
}

func projectileDidCollideWithMonster(projectile:SKSpriteNode, monster:SKSpriteNode) {
    println("Hit")
    changeScore(1)
    changeAmo(true)
    projectile.removeFromParent()
    monster.removeFromParent()
}

然后发生的事情是,有时射弹有时会同时击中两个怪物。

Then what is happening is that a projectile sometimes hit TWO monsters at once.

这种情况发生时-didBeginContact方法崩溃,说secondBody为nil。

When this happens - didBeginContact method crashes saying that secondBody is nil.

经过深入研究,我发现了原因:

After a thorough research I found out the reason:

当弹丸一次与另外两个节点碰撞时-此方法运行两次。第一次运行后-如果将bodyA作为射弹,将bodyB作为怪物-将它们传递给 projectileDidCollideWithMonster ,然后将它们都删除。然后它立即再次运行,但在那一刻,弹丸不复存在,无法分配它的节点而崩溃。

when projectile collides with two other nodes at once - this method runs two times. After the first run - if gets bodyA as projectile, bodyB as a monster - passes them on to projectileDidCollideWithMonster and it removes them both. then it runs immediately again but at that moment projectile doesn't exist anymore and it crashes not able to assign it's node.

我不知道如何克服这个问题:(

I have no idea how to overcome this:( any suggestions, please?

解决方案:由于下面的想法,我做了一些更改。

SOLUTION: Thanks to ideas below i did some changes.

添加了数组并类顶部的触发器:

added and array and a trigger at the top of the class:

    var bodiesToBeRemoved = [SKSpriteNode]()
    var shouldRemoveBodies = false

并进行了以下修改:

 func projectileDidCollideWithMonster(projectile:SKSpriteNode, monster:SKSpriteNode) {
 /* Called when collisions is detected and collided nodes are passed to it */
    //score and stuff
    println("Hit")
    changeScore(1)
    changeAmo(true)

    //collect the nodes to be removed
    bodiesToBeRemoved.append(projectile)
    bodiesToBeRemoved.append(monster)

    //change the trigger to remove collected nodes later on
    shouldRemoveBodies=true

}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */

    //check the trigger
    if shouldRemoveBodies == true {
        println("\(bodiesToBeRemoved.count)")
        //remove collected nodes
        for var i = 0; i<bodiesToBeRemoved.count; i++ {
            bodiesToBeRemoved[i].removeFromParent()
        }

        //reset array
        bodiesToBeRemoved.removeAll(keepCapacity: false)

        //reset the trigger
        shouldRemoveBodies = false
    } else {
        //do nothing:)
    }

}


推荐答案

与其立即移除弹丸,不如立即将其标记为移除(例如,通过设置布尔标志,或者将其添加到某个集合中(如果尚未包含在集合中)。然后,在下一次物理检查之前(例如,在此帧末尾),检查并清除所有标记为要清除的射弹。

Instead of removing your projectile immediately, just mark it for removal (e.g. by setting a boolean flag, or adding it to some collection if it's not already in the collection). Then later, before the next physics check (e.g. at the end of this frame), go through and remove all projectiles marked for removal.

这篇关于当弹丸击中两个“怪兽”时, didBeginContact方法崩溃。我知道为什么,但我不知道如何避免的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆