Alex Merlin
Alex Merlin

Reputation: 451

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

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.

Upvotes: 3

Views: 223

Answers (2)

Steve Ives
Steve Ives

Reputation: 8134

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.

Upvotes: 0

Alessandro Ornano
Alessandro Ornano

Reputation: 35372

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

Upvotes: 4

Related Questions