Diego Benítez Diego Benítez - 5 months ago 10
Swift Question

How to remove an sprite when game is over?

I have been stuck in this part, I have been trying to removeFromParent but it doesnt work. In my game when an enemy colide 3 times with the player the game is over, the problem is that the enemies continue coming for some seconds and then dissapear but continue makeing damage to the player.

func didBeginContact(contact: SKPhysicsContact) {
let body1 = contact.bodyA.node as! SKSpriteNode
let body2 = contact.bodyB.node as! SKSpriteNode

if ((body1.name == "circuloPrincipal") && (body2.name == "enemigo")) {

colisionPrincipal(body2)



}else {

((body1.name == "enemigo") && (body2.name == "circuloPrincipal"))

colisionPrincipal(body1)


}


}




func colisionPrincipal(enemigo: SKSpriteNode) {


if hits < 2 && circuloPrincipal.color != enemigo.color{

shakeFrame(scene!)

circuloPrincipal.runAction(SKAction.scaleBy(1.5, duration:0.5))

enemigo.removeFromParent()

let particula = SKEmitterNode(fileNamed: "particulas.sks")

particula?.position = enemigo.position
particula?.hidden = false

particula?.runAction(SKAction.fadeOutWithDuration(0.8))


self.addChild(particula!)

hits += 1


}else if circuloPrincipal.color == enemigo.color {

enemigo.physicsBody?.affectedByGravity = false

enemigo.physicsBody?.dynamic = true

enemigo.removeFromParent()

score += 1

scoreLabel.text = "\(score)"


}else {

shakeFrame(scene!)

gameStarted = false

enemigo.removeFromParent()
enemigoTimer.invalidate()

highscoreLabel.runAction(SKAction.fadeInWithDuration(0.5))


if score > highscore {

let highscoreDefault = NSUserDefaults.standardUserDefaults()

highscore = score

highscoreDefault.setInteger(highscore, forKey: "highscore")

highscoreLabel.text = "Best: \(highscore)"

}

}

}

Answer

OK, so I don't have all that much information about your game to go by, but if you don't want the enemies to keep damaging the player the quick and dirty fix would be to add a guard to the top of your didBeginContact function:

func didBeginContact(contact: SKPhysicsContact) {
    guard hits < 3 else {
        return
    }
    let body1 = contact.bodyA.node as! SKSpriteNode
    let body2 = contact.bodyB.node as! SKSpriteNode

    if ((body1.name == "circuloPrincipal") && (body2.name == "enemigo")) {
       colisionPrincipal(body2)
    }else {
       ((body1.name == "enemigo") && (body2.name == "circuloPrincipal"))
       colisionPrincipal(body1)
    }
}

This should at least prevent anything to get called based on contacts after the required number of hits have occurred. As for cleaning up the sprites, this sounds rather simple (removeFromParent at the appropriate time) but I haven't got a clue about how you handle your game-states so it's hard to comment any further.

Personally I'd trigger it from the update() function if the required state has happened...

Comments