简体   繁体   English

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

[英]Node not being removed from parent (spritekit)

Create enemy 创造敌人

touchesBegan and didBegin contact function touchesBegan和didBegin接触功能

My enemy node is not being removed from the scene every time my sword node touches it. 每次我的剑节点触碰到我的敌人节点时,都不会从场景中移除它。 I'm just wondering if anyone could explain to me what I'm doing wrong? 我只是想知道是否有人可以向我解释我做错了什么?

(UPDATE BELOW) (更新如下)

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

} }

(Ive attached my whole level2 class) Thank you so much for the suggestion; (我已经完成了整个Level2的课堂)非常感谢您的建议; however, when I tried implementing this I still run into the same problem (im running this on the iphone simulator) Im wondering whether the error is with my enum or my implementation of my physics with my nodes 但是,当我尝试实现这一点时,我仍然遇到相同的问题(即在iphone模拟器上运行该问题)我想知道错误是我的枚举还是我的节点物理实现?

Try this: 尝试这个:

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

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

You were only testing if bodyA is equal to the enemy , however, bodyA may be equal to the sword instead . 你只是测试,如果bodyA 等于 enemy ,但是, bodyA可以等于sword 代替

You do not want to remove "enemy" because "enemy" is always the last monster you added. 您不想删除“敌人”,因为“敌人”始终是您添加的最后一个怪物。 You need to check which contactBody is the enemy so you can remove it. 您需要检查哪个contactBody是敌人,以便将其删除。 You can do that by guaranteeing which node you want to associate as A, and which you want to associate as B by looking at the categoryBitMask value: 您可以通过查看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()
    }
}

Of course this will lead to problems with multiple collisions, so instead you may want to do: 当然,这将导致多次碰撞的问题,因此您可能需要这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM