我想添加一堆不同的岩石和其他危险的物体,玩家可以碰撞和死亡。我该如何有效地做到这一点?现在如果我复制粘贴这些函数,它肯定会工作。但这似乎是大量不必要的代码。
旁注:我对xcode,swift 2和Sprite套件很陌生。

func didBeginContact(contact: SKPhysicsContact) {
    let firstBody : SKPhysicsBody = contact.bodyA
    let secondBody : SKPhysicsBody = contact.bodyB

    if ((firstBody.categoryBitMask == PhysicsCategory.Rock) && (secondBody.categoryBitMask == PhysicsCategory.Bullet) || (firstBody.categoryBitMask == PhysicsCategory.Bullet) && (secondBody.categoryBitMask == PhysicsCategory.Rock)) {

        CollisionWithBullet(firstBody.node as! SKSpriteNode, Bullet: secondBody.node as! SKSpriteNode)

    }

    if ((firstBody.categoryBitMask == PhysicsCategory.Rock) && (secondBody.categoryBitMask == PhysicsCategory.Player) || (firstBody.categoryBitMask == PhysicsCategory.Player) && (secondBody.categoryBitMask == PhysicsCategory.Rock)) {

        CollisionWithPlayer(firstBody.node as! SKSpriteNode, Player: secondBody.node as! SKSpriteNode)

    }
}

func CollisionWithPlayer(Rock: SKSpriteNode, Player: SKSpriteNode){
    let ScoreDefault = NSUserDefaults.standardUserDefaults()
    ScoreDefault.setValue(Score, forKey: "Score")
    ScoreDefault.synchronize()

    let HighscoreDefault = NSUserDefaults.standardUserDefaults()
    if (HighscoreDefault.valueForKey("Highscore") != nil){
        Highscore = HighscoreDefault.valueForKey("Highscore") as! NSInteger
    } else {
        Highscore = 0
    }

    if (Score > Highscore){

        let HighscoreDefault = NSUserDefaults.standardUserDefaults()
        HighscoreDefault.setValue(Score, forKey: "Highscore")

    }

    self.view?.presentScene(EndScene())
    ScoreLabel.removeFromSuperview()
}

最佳答案

所以你可能要找的是位或运算符和位与运算符。
使用SpriteKit,PhysicsBody可以有多个分配给它们的类别。例如,如果我们设置了以下类别:

enum CollisionCategories : UInt32 {
    case Player = 1
    case Enemy = 2
    case Rock = 4
    case Bullet = 8
}

我们可以设置播放器类别并按如下方式联系位掩码:
let player = SKSpriteNode(color: UIColor.blackColor(), size: CGSize(width: 50, height: 50))
player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size)
player.physicsBody?.categoryBitMask = CollisionCategories.Player.rawValue
player.physicsBody?.contactTestBitMask = CollisionCategories.Enemy.rawValue

以及两个敌人类别和接触位掩码,如下所示:
let rockEnemy = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: 25, height: 25))
rockEnemy.physicsBody = SKPhysicsBody(rectangleOfSize: rockEnemy.size)
rockEnemy.physicsBody?.categoryBitMask = CollisionCategories.Enemy.rawValue | CollisionCategories.Rock.rawValue
rockEnemy.physicsBody?.contactTestBitMask = CollisionCategories.Player.rawValue

let bulletEnemy = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 25, height: 25))
bulletEnemy.physicsBody = SKPhysicsBody(rectangleOfSize: bulletEnemy.size)
bulletEnemy.physicsBody?.categoryBitMask = CollisionCategories.Enemy.rawValue | CollisionCategories.Bullet.rawValue
bulletEnemy.physicsBody?.contactTestBitMask = CollisionCategories.Player.rawValue

注意,在设置类别位掩码时,我使用的是按位或运算符(“|”)。这是同时将位掩码设置为两个不同类别的好方法。这样,一个精灵既可以是一块石头,也可以是一个敌人,或者是一颗子弹和一个敌人,等等。
请参阅下面的图片,了解引擎盖下面按位发生的事情。
ios - 在SpriteKit中简化碰撞和玩家死亡-LMLPHP
在我们的contact detection函数中,我们可以使用按位AND运算符('&')来查看我们的contact是否具有特定的类别。
func didBeginContact(contact: SKPhysicsContact) {
    let firstBody : SKPhysicsBody = contact.bodyA
    let secondBody : SKPhysicsBody = contact.bodyB

    if (firstBody.categoryBitMask & CollisionCategories.Player.rawValue == CollisionCategories.Player.rawValue &&
        secondBody.categoryBitMask & CollisionCategories.Enemy.rawValue == CollisionCategories.Enemy.rawValue) {
            print("The collision was between the Player and an Enemy")
    }
    else if (firstBody.categoryBitMask & CollisionCategories.Enemy.rawValue == CollisionCategories.Enemy.rawValue &&
        secondBody.categoryBitMask & CollisionCategories.Player.rawValue == CollisionCategories.Player.rawValue) {
            print("The collision was between the Player and an Enemy")
    }

}

这样,您可以有多个类别的敌人,但您始终可以执行一次检查,看看节点是否实际上是敌人,而不管它们可能拥有哪些其他类别。

关于ios - 在SpriteKit中简化碰撞和玩家死亡,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34372894/

10-08 21:32