Swift / SpriteKit访问对象的变量+删除节点

时间:2015-11-14 17:12:28

标签: swift variables collections sprite-kit collision-detection

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

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

我想根据玩家的攻击和其他方式减去僵尸的健康点。当玩家击中僵尸时,僵尸应该失去生命点。当僵尸击中玩家时,玩家应失去生命点。每个玩家/僵尸都获得了健康点和攻击值。你如何在didBeginContact函数中访问它们?我也有多个僵尸存储在var Zombies:[Zombie] = [],因为每个僵尸都应该有它的通用值。怎么可能只是我攻击的僵尸失去了健康点。

PS:我的class Player看起来像这样:

class Player{
var node: SKSpriteNode
var xPos = CGFloat()
var yPos = CGFloat()
var healthPoints: Int
var attack: Int

init(node: SKSpriteNode, healthPoints: Int, attack: Int){
    self.node = node
    self.healthPoints = healthPoints
    self.attack = attack
}

}

1 个答案:

答案 0 :(得分:0)

首先,您可以将firstBodysecondBody对象(检查后为僵尸的对象)与node对象中的Zombie字段进行比较,如下所示:

func changeHelthPointsForZombieWithNode(node: SKSpriteNode, andPoints points: Int) {
    for zombie in Zombies {
        if zombie.node == node {
            zombie.healthPoints -= points
            return
        }
    }
}

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"){
        changeHelthPointsForZombieWithNode(secondBody, andPoints: Player.attack)
    } else if(firstBody.name == "Zombie" && secondBody.name == "Player"){
        changeHelthPointsForZombieWithNode(firstBody, andPoints: Player.attack)
    }
}

如果Zombieclass类型对象,那将是有效的,如果它是struct对象,则需要使用for var i = 0; i < Zombies.count; ++i循环并调用对象字段形式{{1索引为Zombies

的索引

其次,您可以附加需要更改节点的字段,如下所示:

i

然后将这种类型的对象追加到场景中:

class ZombieNode: SKSpriteNode {
    var healthPoints: Int
    var attack: Int
    ...
    // create custom init method with this params
    ...
}

在这种情况下,您可以在func addZombie(xPos: CGFloat, yPos: CGFloat){ var zombieNode = ZombieNode(imageNamed: "zombie", healthPoints: 100, attack: 10) ... ... addChild(zombieNode) } 方法对象中找到您需要的内容:

didBeginContact

修改新代码:

您的func didBeginContact(contact: SKPhysicsContact) { let firstBody = contact.bodyA.node as! ZombieNode let secondBody = contact.bodyB.node as! ZombieNode if(firstBody.name == "Player" && secondBody.name == "Zombie"){ secondBody.helthPoints -= Player.attack } else if(firstBody.name == "Zombie" && secondBody.name == "Player"){ firstBody.helthPoints -= Zombie.attack } } 个对象未从场景中删除,因为您尚未将其删除。每当你在这行代码中创建赞比亚时,你就有一个变量zombie

zombieNode

每次为其分配一个新值,结果zombieNode = SKSpriteNode(imageNamed: "zombie") 是指向上一个创建节点的指针。这种方法适用于播放器,因为它是单个对象,并且不接受一组对象。事实上,每当你的僵尸死亡时,你试图删除这个最后创建的对象。这就是为什么这不起作用。要修复它,您需要执行以下操作:

首先,你需要删除这行代码:

zombieNode

var zombieNode = SKSpriteNode() 方法中创建如下的新节点:

addZombie

let zombieNode = SKSpriteNode(imageNamed: "zombie") 方法中,您可以删除僵尸节点,如下所示:

changeHealthPointsForZombieWithNode

当你删除节点时,也可以从if(zombie.healthPoints <= 0){ node.removeFromParent() } 数组中删除对象。