【问题标题】:How to remove node from parent if touched more than once?如果多次触摸,如何从父节点中删除节点?
【发布时间】:2016-07-21 07:11:16
【问题描述】:

我正在制作一个游戏,当按下按钮时,子弹会射向坏人。我做了一个函数,每当它被调用时,它都会增加更多的坏人。

代码如下:(这个方法被多次调用)

 func BadGuyPosition()
    let BadGuyCircle = SKSpriteNode(imageNamed: "CircleBadGuy")
    BadGuyCircle.zPosition = 1
    //var mininmum = self.size.width / 600
    let TooMuch = self.size.height - 60

    let PointToShow = UInt32(TooMuch)

    BadGuyCircle.position = CGPointMake(CGRectGetMaxX(self.frame) + 20 , CGFloat(arc4random_uniform(PointToShow) ))

    let action2 = SKAction.moveToX(-100, duration: 5.0)
    let remove = SKAction.removeFromParent()

    BadGuyCircle.runAction(SKAction.sequence([action2,remove]))

    //Physics BadGuy
    BadGuyCircle.physicsBody = SKPhysicsBody(rectangleOfSize: BadGuyCircle.size)
    BadGuyCircle.physicsBody?.categoryBitMask = Numbering.Badguy
    BadGuyCircle.physicsBody?.contactTestBitMask = Numbering.Laser
    BadGuyCircle.physicsBody?.affectedByGravity = false
    BadGuyCircle.physicsBody?.dynamic = true

    self.addChild(BadGuyCircle)

我想要这样,如果 2 颗子弹与坏人接触,坏人就会从父母身上移除。

我知道,当 1 颗子弹与敌人接触时,它会从父级中移除。 (这里是代码)

func didBeginContact(contact: SKPhysicsContact) {
    let A : SKPhysicsBody = contact.bodyA
    let B : SKPhysicsBody = contact.bodyB

    if (A.categoryBitMask == Numbering.Badguy) && (B.categoryBitMask == Numbering.Laser) || (A.categoryBitMask == Numbering.Laser) && (B.categoryBitMask == Numbering.Badguy)
    {

        runAction(BadGuyLostSound)
        bulletsTouchedBadGuy(A.node as! SKSpriteNode, Laser: B.node as! SKSpriteNode)

    }









}

func bulletsTouchedBadGuy(BadGuy: SKSpriteNode, Laser: SKSpriteNode){

    Laser.removeFromParent()
    BadGuy.removeFromParent()


}

谁能告诉我如何才能使敌人从父母身上移除需要不止一颗子弹。

【问题讨论】:

    标签: swift sprite-kit swift2


    【解决方案1】:

    删除碰撞节点的最佳方法是使用方法didFinishUpdate,如果您从didBeginContact 中删除或启动一个方法来删除您的节点,您的游戏可能会在搜索同时处于处理过程中的碰撞节点时崩溃删除..

    class BadGuy: SKSpriteNode {
       var badGuyBulletCollisionsCounter: Int = 0
       init() {
           let texture = SKTexture(imageNamed: "CircleBadGuy")
           super.init(texture: texture, color: nil, size: texture.size())
           ...
           // fill this part with your BadGuy code
       }
       required init(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
       }  
    }
    

    声明一个全局变量:

    var nodesToRemove = [SKNode]()
    

    didBeginContact 方法中:

    func didBeginContact(contact: SKPhysicsContact) {
        let A : SKPhysicsBody = contact.bodyA
        let B : SKPhysicsBody = contact.bodyB
        if (A.categoryBitMask == Numbering.Badguy) && (B.categoryBitMask == Numbering.Laser) || (A.categoryBitMask == Numbering.Laser) && (B.categoryBitMask == Numbering.Badguy)
        {
            badGuy = A.node as! BadGuy
            badGuy.badGuyBulletCollisionsCounter += 1
            runAction(BadGuyLostSound)
            bulletsTouchedBadGuy(badGuy, Laser: B.node as! SKSpriteNode)
        }
    }
    

    bulletsTouchedBadGuy 方法中:

    func bulletsTouchedBadGuy(badGuy: BadGuy, laser: SKSpriteNode){
        nodesToRemove.append(laser)
        if badGuy.badGuyBulletCollisionsCounter == 2 {
           nodesToRemove.append(badGuy)
        }   
    }
    

    最后:

    override func didFinishUpdate() 
    {   
         nodesToRemove.forEach(){$0.removeFromParent()}   
         nodesToRemove = [SKNode]()
    }
    

    【讨论】:

    • Alessandro - 我非常努力地尝试通过删除 didBeginContact 中的节点来产生崩溃,但失败了。你见过这种情况吗?
    • 几次但它发生了,我过去不开心,因为我的游戏在苹果商店有这个错误..didBeginContact 可以多次调用,所以它不是删除节点的正确位置.
    • 您好,感谢您回答这个问题,BadGuy: SKSpriteNode 类是否必须在我目前正在处理的类中,还是我必须制作另一个 swift 文件?如果不是,你能告诉我它在哪里吗?谢谢你
    • 我问是因为 badGuypostion 方法每 0.5 秒使用 NSTimer Scheduled Timer 调用一次
    • 您可以在同一个文件中制作所有内容,您的班级上方的 BadGuy 班级
    【解决方案2】:

    使用节点的 userData 来跟踪它的命中状态。当子弹击中 BadGuy 时,检查节点的 userData 以查看它是否已经被击中。如果有,请将其删除;如果没有,说明它有:

    //Add this when creating BadGuy:
    BagGuy.userData = ["HasBeenHit" : false]
    
        func bulletsTouchedBadGuy(BadGuy: SKSpriteNode, Laser: SKSpriteNode){
    
            Laser.removeFromParent()
    
            if BadGuy.userData["HasBeenHit"] == true {
               BadGuy.removeFromParent()
            } else {
               BadGuy.userData["HasBeenHit"] = true
            }
    

    甚至:

            if BadGuy.userData["HasBeenHit"] == true ? BadGuy.removeFromParent() : BadGuy.userData["HasBeenHit"] = true
    

    如果您想将 removeFromParent() 移动到 didFinishUpdate() ,只需按如下方式更改操作:

            if BadGuy.userData["HasBeenHit"] == true {
               BadGuy.userData["HasBeenHitTwice"]
            } else {
               BadGuy.userData["HasBeenHit"] = true
            }
    

    然后在didFinishUpdate() 中删除具有此值集的所有节点,或者根据其他答案构造要删除的节点数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-26
      相关资源
      最近更新 更多