How to remove node from parent if touched more than once?

僤鯓⒐⒋嵵緔 提交于 2020-01-02 07:01:44

问题


I am making a game in which bullets are shot to the bad guy when the button is pressed. I made a function in which whenever it is called it adds more bad guys.

Here is the code: (This method is called multiple times)

 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)

I want it so that the bad guy is removed from the parent if 2 bullets are made in contact with the bad guy.

I got it so that when 1 bullet makes contact with the enemy, it is removed from the parent. (here is the code)

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


}

Can Anyone Please Tell me how can I make so that it would take more than one bullet to make the enemy be removed from parent.


回答1:


The best way to remove your collided nodes is using the method didFinishUpdate, if you remove or launch a method to remove your node from didBeginContact your game could crash searching a collided node that meanwhile is in the process of being removed..

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

Declare a global var :

var nodesToRemove = [SKNode]()

In the didBeginContact method:

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

In the bulletsTouchedBadGuy method :

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

Finally:

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



回答2:


Use the nodes' userData to track it's hit status. When the bullet hits BadGuy, check the nodes' userData to see if it has been hit already. If it has, remove it; if not, indicate that it has :

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

or even:

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

If you want to move the removeFromParent() to didFinishUpdate() , then simply change the action as follows:

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

and then in didFinishUpdate() remove all nodes with this value set, or construct an array of nodes to be removed as per the other answer.



来源:https://stackoverflow.com/questions/38497346/how-to-remove-node-from-parent-if-touched-more-than-once

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!