许多物体之间的Swift / SpriteKit碰撞检测

时间:2015-11-16 17:09:13

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

所以我有两个物体在碰撞时会失去健康点。

func addPlayer(xPos: CGFloat, yPos: CGFloat){
    playerNode = SKSpriteNode(imageNamed: "player")

    playerNode.physicsBody = SKPhysicsBody(circleOfRadius: width/2)
    playerNode.physicsBody!.affectedByGravity = false
    playerNode.physicsBody!.categoryBitMask = PhysicsCategory.Player
    playerNode.physicsBody!.contactTestBitMask = PhysicsCategory.Wall | PhysicsCategory.Zombie
    playerNode.physicsBody!.collisionBitMask = PhysicsCategory.Wall | PhysicsCategory.Zombie
    playerNode.name = "Player"

    player = Player(node: playerNode, healthPoints: 100, attack: 10)
    playerNode.position.x = xPos
    playerNode.position.y = yPos
    playerNode.size = CGSize(width: width, height: width)
    addChild(playerNode)
}

func addZombie(xPos: CGFloat, yPos: CGFloat){

    zombieNode = SKSpriteNode(imageNamed: "zombie")

    zombieNode.physicsBody = SKPhysicsBody(circleOfRadius: width/2)
    zombieNode.physicsBody!.affectedByGravity = false
    zombieNode.physicsBody!.categoryBitMask = PhysicsCategory.Zombie
    zombieNode.physicsBody!.contactTestBitMask = PhysicsCategory.Zombie | PhysicsCategory.Player | PhysicsCategory.Wall
    zombieNode.physicsBody!.collisionBitMask = PhysicsCategory.Zombie | PhysicsCategory.Player | PhysicsCategory.Wall
    zombieNode.name = "Zombie"

    zombie = Zombie(node: zombieNode, healthPoints: 50, attack: 5)
    Zombies.append(zombie!)
    zombieNode.position.x = xPos
    zombieNode.position.y = yPos
    zombieNode.size = CGSize(width: width, height: width)
    addChild(zombieNode)
}

当出现碰撞时,此功能会被激活:

func didBeginContact(contact: SKPhysicsContact) {
    let firstBody = contact.bodyA.node as! SKSpriteNode
    let secondBody = contact.bodyB.node as! SKSpriteNode
    if(firstBody.name == "Player" && secondBody.name == "Zombie"){
        changeHealthPointsForZombieWithNode(secondBody, points: player!.attack)
    } else if(firstBody.name == "Zombie" && secondBody.name == "Player"){
        changeHealthPointsForPlayer(secondBody, points: zombie!.attack)
        print(player!.healthPoints)
    }
}

func changeHealthPointsForZombieWithNode(node: SKSpriteNode, points: Int) {
    for zombie in Zombies {
        if zombie.node == node {
            zombie.healthPoints -= points
            print(zombie.healthPoints)
            if(zombie.healthPoints <= 0){
                zombieNode.removeFromParent()
            }
            return
        }
    }
}

func changeHealthPointsForPlayer(node: SKSpriteNode, points: Int) {
    player!.healthPoints -= points
    if(player!.healthPoints <= 0){
        playerNode.removeFromParent()
        gameOver = true
    }
}

我想根据玩家的攻击和其他方式减去僵尸的健康点。当玩家击中僵尸时,僵尸应该失去生命点。当僵尸击中玩家时,玩家应失去生命点。每个玩家/僵尸都获得了健康点和攻击值。问题是一些僵尸是可以杀戮的并且失去健康而其他(通常是1-3)不能失去健康。这些不能失去健康的僵尸是唯一能够杀死玩家的僵尸。失去健康的僵尸不会造成伤害(为什么?)?所以只能做一件事(攻击或失去健康),尽管他们应该做两件事(攻击和失去健康)。

1 个答案:

答案 0 :(得分:0)

请记住,contact参数中描述的两个物理主体不会以保证顺序传递。在delegate函数内部没有&#34; A是与B碰撞的那个,而不是相反的&#34;。只有&#34; A和B正在碰撞&#34;。也就是说,根据你的游戏机制,你至少有两个选择:

  • 每次碰撞时让玩家和僵尸对彼此造成伤害。
  • 为玩家和僵尸制作SKSpriteNode的子类,其属性为isAttacking,这是一个布尔值,用于确定实体在检测到与其接触时应该造成伤害的时间。对于玩家来说,这个布尔可能会被激活&#34;每按一下按钮。对于僵尸,每隔一段时间,如果足够接近玩家。

此外,您实施的方式是获得双倍的联系人通知。 SpriteKit将通过玩家接触面具和僵尸类别面具检测玩家与僵尸的接触,并通过僵尸接触面罩和玩家类别面具检测僵尸与玩家的接触。你通常不希望这种情况发生。您应该只让其中一个检测到它。我会建议玩家。这样就不需要设置僵尸接触面罩了。只要你在玩家的联系人面具和僵尸的类别掩码中设置僵尸,你就已经有了检测(和一次)。