在SpriteKit中简化碰撞和玩家死亡

时间:2015-12-19 16:31:05

标签: ios swift sprite-kit

我想添加一堆不同的岩石和其他危险物品,玩家可以碰撞并死亡。我该如何有效地做到这一点?现在,如果我复制粘贴这些功能,它肯定会起作用。但它似乎是一大堆不必要的代码。

旁注:我对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()
}

1 个答案:

答案 0 :(得分:0)

所以你在这里寻找的是按位OR运算符和按位AND运算符。

使用SpriteKit,physicsBodies可以分配多个类别。例如,如果我们设置了以下类别:

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

请注意,在设置类别位掩码时,我使用的是按位OR运算符(' |')。这是将位掩码同时设置为两个不同类别的好方法。这样,精灵既可以是摇滚,也可以是敌人,子弹和敌人等等。

请参阅下图,了解引擎盖下发生的事情。

enter image description here

在我们的联系人检测功能中,我们可以使用按位AND运算符('&')来查看我们的联系人是否拥有某个类别。

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")
    }

}

这样,您可以拥有多个类别的敌人,但是您可以随时进行一次检查以查看某个节点是否实际上是敌人,无论他们可能拥有哪些其他类别。