sicvayne
sicvayne

Reputation: 620

one shot kill function in SpriteKit

so I have the following code which kills an enemy with two shots from the player set up inside my didBegin:contact

var bulletCounter : Int = 0 //not declared inside didbegin just to be clear
nodesToRemove = [SKNode]() // not declared inside didbegin just to be clear       

if body1.categoryBitMask == PhysicsCatagory.Bullet && body2.categoryBitMask == PhysicsCatagory.Enemy && (body2.node?.position.y)! < self.size.height{
                //if the bullet has hit the enemy
                bulletCounter += 1
                nodesToRemove.append(body1.node!) // remove bullet always
                switch bulletCounter {
                case 2:
                    nodesToRemove.append(body2.node!) // remove enemy
                    bulletCounter = 0
                    addScore()
                default:break
                }

followed by this

 override func didFinishUpdate()

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

Now for my question, how can I create some sort of instant kill, 1 bullet to kill instead of 2, once the player has touched the shooterNode and make it last for 10 seconds or so?

Upvotes: 2

Views: 132

Answers (1)

Steve Ives
Steve Ives

Reputation: 8134

A 'one-shot kill' is easy to implement, as there is no need to remember that the target has already been hit and to check this on each hit.

var bulletCounter : Int = 0 //not declared inside didbegin just to be clear
nodesToRemove = [SKNode]() // not declared inside didbegin just to be clear       

if body1.categoryBitMask == PhysicsCatagory.Bullet &&
    body2.categoryBitMask == PhysicsCatagory.Enemy &&
    (body2.node?.position.y)! < self.size.height {
        //The bullet has hit the enemy, so remove both and update the score
    body1.node.removeFromParent()
    body2.node.removeFromParent()
    addScore()
    }

EDIT Flexible solution using subclasses of SKSpriteNode

OK - if we subclass bullet & enemy, we can have bullets that do more (or less damage), enemies with more or less health etc, all neatly tracked by the individual nodes.

Here is our new bullet class:

import Foundation
import SpriteKit

class Bullet: SKSpriteNode {

    var damageInflicted = 2 
    var health = 1  { // Possibility for some bullets to be stronger
       didSet {
             if health == 0 {
                removeFromParent()
             }
       }
}

and here is our new enemy:

import Foundation
import SpriteKit

class Enemy: SKSpriteNode {

    var health = 2 {
       didSet {
             if health == 0 {
                removeFromParent()
             }
       }
     var pointValue = 100  // Points for destroying
}

Your code now becomes:

if body1.categoryBitMask == PhysicsCatagory.Bullet && body2.categoryBitMask == PhysicsCatagory.Enemy && (body2.node?.position.y)! < self.size.height{
     // The bullet has hit the enemy
     let enemyNode = contact.bodyA.categoryBitMask == PhysicsCatagory.Enemy ? contact.bodyA.node as! Enemy : contact.bodyB.node as! Enemy
     let bulletNode = contact.bodyA.categoryBitMask == PhysicsCatagory.Bullet ? contact.bodyA.node as! Bullet : contact.bodyB.node as! Bullet
     enemyNode.health -= bulletNode.damageInflicted
     bulletNode.health -= 1 
     addScore(enemyNode.pointValue)
     }

You can update individual bullets and enemies' damageInflicted, health and scoreValues as necessary.

Bullets and enemies will be initialised with :

let bullet = Bullet(imageNamed: "bullet")

and

let enemy = Enemy(imageNamed: "enemy1")

instead of: let bullet = SKSpriteNode(imageNamed: "bullet") etc.

Functions that return an SKNode and which often have ... as SKSpriteNode will now have as bullet and as enemy instead.

Upvotes: 3

Related Questions