How to remove a node from a parent if it is touched multiple times?

I am making a game in which bullets shot a bad guy at the touch of a button. I made a function in which, when called, it adds more bad guys.

Here is the code: (This method is called several 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 the bad guy to leave the parent if 2 bullets are made in contact with the bad guy.

I realized 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 someone tell me how I can make it take more than one bullet so that the enemy is removed from the parent.

+3
source share
2 answers

The best way to remove the didFinishUpdate nodes is to use the didFinishUpdate method, if you delete or run the method to remove your node from didBeginContact , your game may crash in finding the oncoming node, which is in the process of removal in the meantime.

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

Use custom node data to track impact status. When a bullet hits BadGuy, check the user data of the nodes to see if it has already been hit. If it is, 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 removeFromParent() to didFinishUpdate() , just change the action as follows:

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

and then in didFinishUpdate() delete all nodes with this set of values ​​or create an array of nodes that should be deleted according to another answer.

0
source

Source: https://habr.com/ru/post/1260072/


All Articles