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