节点未从父节点移除(Spritekit)

时间:2018-07-14 15:24:59

标签: swift xcode sprite-kit

Create enemy

touchesBegan and didBegin contact function

我的剑节点每次接触都不会从场景中移除我的敌人节点。我只是想知道是否有人可以向我解释我做错了什么?

(下面更新)

import SpriteKit
import GameplayKit
import AVFoundation

class LevelTwo: SKScene, SKPhysicsContactDelegate{
    var levelBg = SKSpriteNode(imageNamed: "level2")
    var hero = SKSpriteNode()
    var enemy = SKSpriteNode()
    var sword = SKSpriteNode()
    var health1 = SKSpriteNode(imageNamed: "playerhplv2")
    var health2 = SKSpriteNode(imageNamed: "playerhplv2")
    var health3 = SKSpriteNode(imageNamed: "playerhplv2")
    var musicPath = URL(fileURLWithPath: Bundle.main.path(forResource: "gameMusic", ofType: "mp3")!)
    var musicGamePlayer = AVAudioPlayer()
    var runMonster =  SKAction()
    var waitMonster =  SKAction()
    var sequenceMonster =  SKAction()
    var repeatMonster = SKAction()

    enum CollisionNum: UInt32{
        case swordNum = 1
        case enemyNum = 2
        case playerNum = 4
    }
    override func didMove(to view: SKView) {
         self.physicsWorld.contactDelegate = self

    ///music
    do{
        musicGamePlayer = try AVAudioPlayer(contentsOf: musicPath)
        musicGamePlayer.prepareToPlay()
        musicGamePlayer.numberOfLoops = -1
        musicGamePlayer.play()
    }
    catch{
        print(error)
    }
    //bg
    levelBg.position = CGPoint(x: 0, y: 0)
    levelBg.zPosition = 1
    levelBg.size = levelBg.texture!.size()
    levelBg.setScale(1.25)
    self.addChild(levelBg)

    //hero
    let playerTexture = SKTexture(imageNamed: "main")
    hero = SKSpriteNode(texture: playerTexture)
    hero.position  = CGPoint(x: 0, y: 0)
    hero.zPosition = 2
    hero.setScale(0.6)
    hero.physicsBody = SKPhysicsBody(texture: playerTexture, size: CGSize(width: hero.size.width, height: hero.size.height))
    hero.physicsBody!.categoryBitMask = CollisionNum.playerNum.rawValue
    hero.physicsBody!.collisionBitMask = CollisionNum.enemyNum.rawValue  //player is allowed to bump into rocks and skulls
    hero.physicsBody!.contactTestBitMask = CollisionNum.enemyNum.rawValue // same as collisions
    hero.physicsBody!.isDynamic = false
    self.addChild(hero)


    //health1
    health1.position = CGPoint(x: 130, y: 150)
    health1.zPosition = 3
    health1.setScale(0.75)
    self.addChild(health1)

    //health2
    health2.position = CGPoint(x: 230, y: 150)
    health2.zPosition = 3
    health2.setScale(0.75)
    self.addChild(health2)

    //health3
    health3.position = CGPoint(x: 320, y: 150)
    health3.zPosition = 3
    health3.setScale(0.75)
    self.addChild(health3)

    runMonster = SKAction.run(addMonster)
    waitMonster = SKAction.wait(forDuration: 0.3)
    sequenceMonster = SKAction.sequence([runMonster,waitMonster])
    repeatMonster = SKAction.repeatForever(sequenceMonster)
    run(repeatMonster)


}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches{
        let locale = touch.location(in: self)
        hero.position.x = locale.x
        hero.position.y = locale.y
    }
}
func addMonster(){
    //random position based off the bg size
    let monsterHigherX = Int(levelBg.size.width)
    let monsterHigherY = Int(levelBg.size.height)
    let monsterLowerX = monsterHigherX * -1
    let monsterLowerY = monsterHigherY * -1

    let randomLocaleX = Int(arc4random_uniform(UInt32(monsterHigherX - monsterLowerX))) + monsterLowerX
    let randomLocaleY = Int(arc4random_uniform(UInt32(monsterHigherY - monsterLowerY))) + monsterLowerY
    let movementEnemy = SKAction.moveBy(x: -5, y: -5, duration: 0.2)
    let movementForever = SKAction.repeatForever(movementEnemy)

    let enemyTexture = SKTexture(imageNamed: "boss0")
    enemy = SKSpriteNode(texture: enemyTexture)
    enemy.zPosition = 2
    enemy.setScale(0.5)
    enemy.position = CGPoint(x: randomLocaleX, y: randomLocaleY)
    enemy.physicsBody = SKPhysicsBody(texture: enemyTexture, size: CGSize(width: enemy.size.width, height: enemy.size.height))
    enemy.physicsBody!.isDynamic = true
    enemy.physicsBody!.affectedByGravity = false
    enemy.physicsBody!.categoryBitMask = CollisionNum.enemyNum.rawValue
    enemy.physicsBody!.collisionBitMask = CollisionNum.swordNum.rawValue
    enemy.physicsBody!.contactTestBitMask = CollisionNum.swordNum.rawValue
    enemy.run(movementForever)
    self.addChild(enemy)

}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let swordTexture = SKTexture(imageNamed: "blade-0")
        sword = SKSpriteNode(texture: swordTexture)
        sword.setScale(0.50)
        sword.zPosition = 2
        sword.position = hero.position
        sword.physicsBody = SKPhysicsBody(texture: swordTexture, size: CGSize(width: sword.size.width, height: sword.size.height))
        sword.physicsBody!.velocity = CGVector(dx: 1200, dy:0)
        sword.physicsBody!.isDynamic = true
        sword.physicsBody!.affectedByGravity = true
        sword.physicsBody!.usesPreciseCollisionDetection = true
        sword.physicsBody!.categoryBitMask = CollisionNum.swordNum.rawValue
        sword.physicsBody!.collisionBitMask = CollisionNum.enemyNum.rawValue
        sword.physicsBody!.contactTestBitMask = CollisionNum.enemyNum.rawValue
        self.addChild(sword)

}
func didBegin(_ contact: SKPhysicsContact) {
    let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
    if  collision == CollisionNum.swordNum.rawValue | CollisionNum.enemyNum.rawValue {
        enemy.removeFromParent()
    }
}
override func update(_ currentTime: TimeInterval) {
}

}

(我附加了我的整个level2班)非常感谢您的建议;但是,当我尝试实现此目标时,我仍然遇到相同的问题(即在iphone模拟器上运行此问题)。我想知道错误是我的枚举还是节点的物理实现

2 个答案:

答案 0 :(得分:0)

尝试一下:

func didBegin(_ contact: SKPhysicsContact) {
    let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    if collision == CollisionNum.swordNum.rawValue | CollisionNum.enemyNum.rawValue {
        enemy.removeFromParent()
    }
}

您仅在测试bodyA 是否等于enemy ,但是,bodyA可能等于sword

答案 1 :(得分:0)

您不想删除“敌人”,因为“敌人”始终是您添加的最后一个怪物。您需要检查哪个contactBody是敌人,以便将其删除。您可以通过查看categoryBitMask值来保证要关联为A的节点和要关联为B的节点来做到这一点:

func didBegin(_ contact: SKPhysicsContact) {
    //This guarantees the lower categoryBitMask (Providing you are only using one) is in A
    let bodyA = contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask ? contact.bodyA : contact.bodyB
    let bodyB = contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask  ? contact.bodyB : contact.bodyA   


    if  bodyA.categoryBitMask == CollisionNum.swordNum.rawValue && bodyB.categoryBitMask == CollisionNum.enemyNum.rawValue {
        bodyB.node.removeFromParent()
    }
}

当然,这会导致多次碰撞的问题,所以您可能需要这样做:

var removeNodes = SKNode()
func didBegin(_ contact: SKPhysicsContact) {
    //This guarantees the lower categoryBitMask (Providing you are only using one) is in A
    let bodyA = contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask ? contact.bodyA : contact.bodyB
    let bodyB = contact.bodyA.categoryBitMask > contact.bodyB.categoryBitMask  ? contact.bodyB : contact.bodyA   


    if  bodyA.categoryBitMask == CollisionNum.swordNum.rawValue && bodyB.categoryBitMask == CollisionNum.enemyNum.rawValue {
        bodyB.node.moveToParent(removeNodes)
    }
}

func didFinishUpdate(){
   removeNodes.removeAllChildren()
}