Reputation: 451
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
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
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