SpriteKit检测多次碰撞而不是一次(Swift 3)

时间:2017-08-18 07:32:15

标签: ios swift sprite-kit collision-detection skspritenode

我的SKScene Class中有3个SKSpriteNode。其中一个是玩家,另一个是金牌和不可见的完成对象,例如当玩家触摸它时,游戏结束。我的问题是,当玩家碰撞黄金时,他的黄金预算应该只增加50金币。但是,Xcode检测到多次碰撞和黄金预算多次增加。检测到50-60碰撞而不是一次碰撞。我研究了如何解决这个问题。我发现我应该使用Bool,我试图设置bool但它并没有解决我的问题。有没有人可以帮助我如何检测一次碰撞?这是我的GameScene类代码:

import SpriteKit
import GameplayKit

class level3: SKScene, SKPhysicsContactDelegate {

    let playerFileName = "player"
    let starFileName = "50Gold"
    let goalFileName = "goal"
    let playerCategory   : UInt32 = 0x1 << 1
    let goalCategory : UInt32 = 0x1 << 2
    let starCategory : UInt32 = 0x1 << 3

    override func didMove(to view: SKView) {
        super.didMove(to: view)
        physicsWorld.contactDelegate = self

        let goal = childNode(withName: goalFileName) as! SKSpriteNode
        let player = childNode(withName: playerFileName) as! SKSpriteNode
        let star = childNode(withName: starFileName) as! SKSpriteNode

        player.physicsBody!.categoryBitMask = playerCategory
        goal.physicsBody!.categoryBitMask = goalCategory

        star.physicsBody?.collisionBitMask = 1
        player.physicsBody?.collisionBitMask = 1
        goal.physicsBody?.collisionBitMask = 1
        goal.physicsBody?.isDynamic = true

        goal.physicsBody!.contactTestBitMask = playerCategory

        player.physicsBody?.isDynamic = true
        star.physicsBody?.isDynamic = true
        player.physicsBody?.contactTestBitMask = starCategory

        star.physicsBody?.categoryBitMask = starCategory

        func didBegin(_ contact: SKPhysicsContact) {

            // 1
            var firstBody: SKPhysicsBody
            var secondBody: SKPhysicsBody
            // 2
            if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
                firstBody = contact.bodyA
                secondBody = contact.bodyB
            } else {
                firstBody = contact.bodyB
                secondBody = contact.bodyA
            }

            if firstBody.categoryBitMask == playerCategory && secondBody.categoryBitMask == goalCategory {

                contact.bodyB.node?.removeFromParent()

            }

            if firstBody.categoryBitMask == playerCategory && secondBody.categoryBitMask == starCategory {

                PlaySceneViewController.instance.gold += 50
                print(PlaySceneViewController.instance.gold)

                contact.bodyB.node?.removeFromParent()

            }

        }
    }
}

1 个答案:

答案 0 :(得分:0)

是的 - 这发生了。处理它的方法(你不能让sprite-kit在某些情况下多次调用didBegin)是为了确保你的联系人代码适应这种情况,并且多次处理合同不会导致问题(例如多次添加分数,删除多个生命,尝试访问已被删除的节点或physicsB等。)

有关更多详细信息和可能的解决方案,请参阅以下答案:https://stackoverflow.com/a/44384390/1430420