touch location from all contacted bodies - swift

Good Morning,
How can I get the location of a contact between two Physicsbody via allContactedBodies?
Because of the structure of my App I cant use touchesBegan method from the Physicsbody but have to check it manually via allContactedBodies() from a Spritekit. But is there a method to get also the point where the touch occurred?
This is how I check for a contact but now I need also the position of the contact
if let unwrapped_allContactedBodies = spriteObject.spriteNode.physicsBody?.allContactedBodies() {
if spriteObject.spriteNode.physicsBody?.allContactedBodies().count ?? 0 > 0 {
return checkForContact(contactedBodies: unwrapped_allContactedBodies, parameter: value)
} else {
return 0.0
}
} else {
return 0.0
} ´´´
Any Ideas?

You can use the contact.contactPoint property. You will have to implement the SKPhysicsContactDelegate.
Example:
enum CollisionTypes: UInt32{
case nodeAColliding = 1
case nodeBColliding = 2
}
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
}
func createNodes(){
let nodeA = SKSpriteNode(imageNamed: "nodeAImage")
nodeA.name = "nodeA"
nodeA.zPosition = 2
nodeA.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 50 , height: 50))
nodeA.position = //some CGpoint
nodeA.physicsBody?.categoryBitMask = CollisionTypes.nodeAColliding.rawValue
nodeA.physicsBody?.contactTestBitMask = CollisionTypes.nodeBColliding.rawValue
nodeA.physicsBody?.collisionBitMask = CollisionTypes.nodeBColliding.rawValue
addChild(nodeA)
let nodeB = SKSpriteNode(imageNamed: "nodeBImage")
nodeB.name = "nodeB"
nodeB.zPosition = 2
nodeB.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 50 , height: 50))
nodeB.position = //some CGpoint
nodeB.physicsBody?.categoryBitMask = CollisionTypes.nodeBColliding.rawValue
nodeB.physicsBody?.contactTestBitMask = CollisionTypes.nodeAColliding.rawValue
nodeB.physicsBody?.collisionBitMask = CollisionTypes.nodeAColliding.rawValue
addChild(nodeB)
}
func didBegin(_ contact: SKPhysicsContact){
guard let contactedNodeA = contact.bodyA.node else {return}
guard let contactedNodeB = contact.bodyB.node else {return}
print(contact.contactPoint)
if contactedNodeA.name == "nodeA"{
//Do something
}
if contactedNodeA.name == "nodeB"{
//Do something
}
}
}
note: I have not tested this code in the compiler.

Related

How detect collision between a box object and ball

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let location = touch.location(in: self) // locates touches on the screen
let objects = nodes(at: location) // shows all objects were screen was touched
if objects.contains(editLabel) { // checking if appropriate array of objects contains the editLabel
editingMode.toggle()
} else {
if editingMode {
let size = CGSize(width: Int.random(in: 16...128), height: 16)
let box = SKSpriteNode(color: UIColor(red: CGFloat.random(in: 0...1), green: CGFloat.random(in: 0...1), blue: CGFloat.random(in: 0...1), alpha: 1), size: size)
box.zRotation = CGFloat.random(in: 0...3)
box.position = location // add the box ob ject were the user taps
box.name = "box"
box.physicsBody = SKPhysicsBody(rectangleOf: box.size)
box.physicsBody!.contactTestBitMask = box.physicsBody!.collisionBitMask
box.physicsBody?.isDynamic = false // box object will not move when impact happens
addChild(box) // box object will be added to the screen
} else if usedBalls != 0 {
let ball = SKSpriteNode(imageNamed: allBalls.randomElement() ?? "ballRed.png") // pulls out the red ball from app bundle
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width / 2.0) // animates the ball object
ball.physicsBody!.contactTestBitMask = ball.physicsBody!.collisionBitMask
ball.physicsBody?.restitution = 0.4 // determines the ball object bounciness
ball.position = location // ball will appear where the user tapped on the screen
ball.name = "ball"
// ball.position = CGPoint (x: 550, y: 700)
addChild (ball) // adds the ball object to the screen
usedBalls -= 1
}
}
}
func makeBouncer(at position: CGPoint) {
let bouncer = SKSpriteNode(imageNamed: "bouncer.png")
bouncer.position = position
bouncer.physicsBody = SKPhysicsBody(circleOfRadius: bouncer.size.width / 2.0)
bouncer.physicsBody?.isDynamic = false // bouncer object is fixed to the bottom of the screen
addChild(bouncer)
}
func makeSlot(at position: CGPoint, isGood: Bool) {
var slotBase: SKSpriteNode
var slotGlow: SKSpriteNode
if isGood {
slotBase = SKSpriteNode(imageNamed: "slotBaseGood.png")
slotGlow = SKSpriteNode(imageNamed: "slotGlowGood.png")
slotBase.name = "good"
} else {
slotBase = SKSpriteNode(imageNamed: "slotBaseBad.png")
slotGlow = SKSpriteNode(imageNamed: "slotGlowBad.png")
slotBase.name = "bad"
}
slotBase.position = position
slotGlow.position = position
slotBase.physicsBody = SKPhysicsBody(rectangleOf: slotBase.size)
slotBase.physicsBody?.isDynamic = false
addChild(slotBase)
addChild(slotGlow)
let spin = SKAction.rotate(byAngle: .pi, duration: 10)
let spinForever = SKAction.repeatForever(spin)
slotGlow.run(spinForever)
}
func collisionBetween(ball: SKNode, object: SKNode) {
if object.name == "good" { // green slot
destroy(ball: ball)
score += 1
usedBalls += 1
} else if object.name == "bad" { // red slot
destroy(ball: ball) // the ball will be removed once drops into a green or red slot
score -= 1
}
}
func boxandballCollision(box: SKNode, ball: SKNode) {
if ball.name == "ball" {
destroyObject(box: box)
}
}
func destroyObject(box: SKNode) {
if let fireParticles = SKEmitterNode(fileNamed: "FireParticles") {
fireParticles.position = box.position
addChild(fireParticles)
}
box.removeFromParent() // box should be removed when a ball will hit it
}
func destroy(ball: SKNode) {
if let fireParticles = SKEmitterNode(fileNamed: "FireParticles") {
fireParticles.position = ball.position
addChild(fireParticles)
}
ball.removeFromParent() // ball object is removed from scene when hits a slot
}
func didBegin(_ contact: SKPhysicsContact) {
guard let nodeA = contact.bodyA.node else { return }
guard let nodeB = contact.bodyB.node else { return }
if nodeA.name == "ball" {
collisionBetween(ball: nodeA, object: nodeB)
} else if nodeB.name == "ball" {
collisionBetween(ball: nodeB, object: nodeA)
}
}
func begin(_ contact: SKPhysicsContact) {
guard let nodeA = contact.bodyA.node else { return }
guard let nodeB = contact.bodyB.node else { return }
if nodeA.name == "box" {
boxandballCollision(box: nodeA, ball: nodeB)
} else if nodeB.name == "box" {
boxandballCollision(box: nodeB, ball: nodeA)
}
}
I want to remove any box object when a ball will hit it, is just a simple game for studying purposes, but I'm struggling with it. I have used exactly same methods for the box object and this to get notifications about every collision " box.physicsBody!.contactTestBitMask = box.physicsBody!.collisionBitMask".

touchesBegin not being called on Sprit Node

I have SpritNodes that are in my scene and I want a method to be called when I touch it. I have isUserInteractionEnabled set to true for my node, but touchesBegan still does not get called when I touch the nodes. (Note: I am using Swift 3.0)
Code:
import SpriteKit
class MainScene: SKScene, SKPhysicsContactDelegate {
var didStart = false
var background = SKSpriteNode(imageNamed: "background")
var backDrop = SKShapeNode()
var emailNodes: [SKSpriteNode] = []
let emailCatagory: UInt32 = 0x1 << 0
let dropCatagory: UInt32 = 0x1 << 1
override func sceneDidLoad() {
startCountDown()
}
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
background.position = CGPoint(x: frame.midX, y:frame.midY)
}
public func startCountDown(){
var times = 4
let countdownTimer = SKLabelNode()
countdownTimer.text = "3"
countdownTimer.position = CGPoint(x: frame.midX, y: frame.midY)
countdownTimer.fontSize = 120.0
countdownTimer.fontName = "Lao MN"
countdownTimer.fontColor = UIColor.black()
backDrop = SKShapeNode()
backDrop = SKShapeNode(rectOf: CGSize(width: frame.width, height: 100))
backDrop.position = CGPoint(x: frame.midX, y: 10)
backDrop.physicsBody = SKPhysicsBody(rectangleOf: backDrop.frame.size)
//backDrop.size = CGSize(width: 1000, height: 2)
backDrop.physicsBody?.affectedByGravity = false
backDrop.physicsBody?.usesPreciseCollisionDetection = true
backDrop.name = "backDrop"
backDrop.physicsBody?.collisionBitMask = 0
backDrop.physicsBody?.categoryBitMask = dropCatagory
addChild(countdownTimer)
addChild(backDrop)
//addChild(background)
Timer.every(1.2.seconds) { (timer: Timer) in
if(times<=0){
timer.invalidate()
countdownTimer.removeFromParent()
self.didStart = true
self.startDropping()
}else{
print("\(times)")
times = times - 1
countdownTimer.text = "\(times)"
}
}
}
func startDropping(){
Timer.every(1.2.seconds) { (timer: Timer) in
let which = Int(arc4random_uniform(2) + 1)
let ee = self.getEmailNode(type: which)
self.addChild(ee)
ee.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: -5.0))
}
}
func getEmailNode(type: Int) -> SKSpriteNode{
var email = SKSpriteNode()
if(type == 1){
email = SKSpriteNode(imageNamed: "normal_email")
email.name = "normal_email"
}
if(type == 2){
email = SKSpriteNode(imageNamed: "classified_email")
email.name = "classified_email"
}
email.setScale(3)
email.position = CGPoint(x: getRandomColumn(), y: frame.height)
email.physicsBody = SKPhysicsBody(rectangleOf: email.frame.size)
email.physicsBody?.usesPreciseCollisionDetection = true
email.physicsBody?.categoryBitMask = emailCatagory
email.isUserInteractionEnabled = true
email.physicsBody?.affectedByGravity = false
email.physicsBody?.collisionBitMask = 0
email.physicsBody?.contactTestBitMask = emailCatagory | dropCatagory
emailNodes.append(email)
return email
}
func getRandomColumn() -> CGFloat{
let which = Int(arc4random_uniform(3) + 1)
let gg = frame.size.width/3
switch(which){
case 1:
return gg / 2
case 2:
return frame.midX
case 3:
return (gg * 3) - gg / 2
default:
return (gg * 3) + gg / 2
}
}
func didBegin(_ contact: SKPhysicsContact) {
if (contact.bodyA.categoryBitMask == dropCatagory) &&
(contact.bodyB.categoryBitMask == emailCatagory) {
let node = contact.bodyB.node as! SKSpriteNode
node.removeFromParent()
while emailNodes.contains(node) {
if let itemToRemoveIndex = emailNodes.index(of: node) {
emailNodes.remove(at: itemToRemoveIndex)
}
}
}
}
func doesContainNode(sk: SKSpriteNode) -> Bool {
for it in emailNodes{
if(it == sk){
return true
}
}
return false
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
enumerateChildNodes(withName: "//*", using:
{ (node, stop) -> Void in
print("\(node.name)")
print("\(node)")
if((node.name?.contains("email")) != nil){
print("Touched!")
}
})
}
}
You should try the following in order to be able to get the user's position and know when the sprite has been touched. Add the following inside the touchesEnabled function.
for touch in touches {
let userTouch = touch.locationInNode(self)
}
And then check if the sprite was touched by using:
node.containsPoint(userTouch)
See if that works. The way you have your code setup, you might need to nest the above function right after checking if it's nil. As for the userInteractionEnabled, I don't use it at all when using the above code.
You do not want userInteractionEnabled set on any of your nodes, you want that only on the scene. Use userInteractionEnabled only when you are subclassing your node, this way you can use touchesBegan inside your subclassed file. What is happening is your touch is going into your node and being absorbed, which does nothing, and is being ignored by the scene since the node absorbed it.
Edit: Sorry #MarkBrownsword I did not see your comment, if you post it as an answer, I will upvote and delete my answer.
I found a solution. I removed isUserInteractionEnabled and touchesBegan was still not being called. So I went through each of the properties of the "email" node and for some reason the following properties made it where touchesBegan would not be called.
email.physicsBody?.affectedByGravity = false
email.physicsBody?.collisionBitMask = 0
So I removed those and now touchesBegan is being properly called.

Day 1 collision detection: swift 3

So I want a game made, this was striped from the Xcode SpriteKit sampler, pretty simple. It will evolve greatly as I get this key issue out of the way. It has a player, Wall's, and a door. Nodes are assigned, player works fine. Wall's attempted for children in self, but crashes with my comments removed. I have a guess as multiple nodes of same name? But the door, when assigned node, for some reason no matter what slowly falls, with no gravity ticked and no gravity coded.
Those are lesser concerns. I come to you today to pick at why my collisions might not be activating my collision argument functions, to enter the house.
Yes I am aware it says contact mapped to the event. It suits my theory I am pretty sure.
//
// GameScene.swift
// Sandbox
//
// Created by M on 7/1/16.
// Copyright © 2016 M. All rights reserved.
//
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var entities = [GKEntity]()
var graphs = [GKGraph]()
private var lastUpdateTime : TimeInterval = 0
private var label : SKLabelNode?
var playerNode : SKSpriteNode?
var wallNode : SKSpriteNode?
var doorNode : SKSpriteNode?
private var spinnyNode : SKShapeNode?
var furnishing : SKSpriteNode?
var playerCategory = 0x1 << 0
var wallCategory = 0x1 << 1
var doorCategory = 0x1 << 2
var pathCategory = 0x1 << 3
func nextRoom() {
let sceneNode = SKScene(fileNamed: "MyScene")
sceneNode?.scaleMode = .aspectFill
// Present the scene
if let view = self.view {
view.presentScene(sceneNode)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
func loadRoom() {
let furnishing = SKSpriteNode(color: #colorLiteral(red: 0.2464724183, green: 0.05352632701, blue: 0.03394328058, alpha: 1), size:CGSize(width:25, height:25))
doorNode?.addChild(furnishing)
}
func enterHouse() {
let newWindow = CGSize(width: 500, height: 500)
doorNode?.scale(to: newWindow)
loadRoom()
}
func exitHouse(){
let oldWindow = CGSize(width: 100, height: 100)
doorNode?.scale(to: oldWindow)
}
override func sceneDidLoad() {
self.lastUpdateTime = 0
physicsWorld.contactDelegate = self
// Get nodes from scene and store for use later
self.playerNode = self.childNode(withName: "//player") as? SKSpriteNode
playerNode?.physicsBody = SKPhysicsBody(rectangleOf: (playerNode?.frame.size)!)
playerNode?.physicsBody?.isDynamic = true
playerNode?.physicsBody?.affectedByGravity = false
playerNode?.physicsBody?.categoryBitMask = UInt32(playerCategory)
playerNode?.physicsBody?.collisionBitMask = UInt32(wallCategory)
playerNode?.physicsBody?.contactTestBitMask = UInt32(doorCategory)
for child in self.children {
/*if child.name == "wall" {
if let child = child as? SKSpriteNode {
wallNode?.physicsBody = SKPhysicsBody(rectangleOf: (wallNode?.frame.size)!)
wallNode?.physicsBody?.isDynamic = false
wallNode?.physicsBody?.categoryBitMask = UInt32(wallCategory)
wallNode?.physicsBody?.collisionBitMask = UInt32(playerCategory)
self.addChild(child)
}
}*/
}
self.doorNode = self.childNode(withName: "door") as? SKSpriteNode
doorNode?.physicsBody?.affectedByGravity = false
doorNode?.physicsBody?.isDynamic = false
doorNode?.physicsBody = SKPhysicsBody(rectangleOf: (doorNode?.frame.size)!)
doorNode?.physicsBody?.categoryBitMask = UInt32(doorCategory)
doorNode?.physicsBody?.contactTestBitMask = UInt32(playerCategory)
}
func touchDown(atPoint pos : CGPoint) {
let fromX = playerNode?.position.x
let fromY = playerNode?.position.y
let toX = pos.x
let toY = pos.y
let resultX = toX - (fromX)!
let resultY = toY - (fromY)!
let newX = (playerNode?.position.x)! + resultX / 10
let newY = (playerNode?.position.y)! + resultY / 10
playerNode?.position.x = newX
playerNode?.position.y = newY
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}
func didBeginContact(contact: SKPhysicsContact) {
//this gets called automatically when two objects begin contact with each other
// 1. Create local variables for two physics bodies
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
// 2. Assign the two physics bodies so that the one with the lower category is always stored in firstBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if secondBody.categoryBitMask == UInt32(doorCategory){
enterHouse()
}
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
// Initialize _lastUpdateTime if it has not already been
if (self.lastUpdateTime == 0) {
self.lastUpdateTime = currentTime
}
// Calculate time since last update
let dt = currentTime - self.lastUpdateTime
// Update entities
for entity in self.entities {
entity.update(withDeltaTime: dt)
}
self.lastUpdateTime = currentTime
}
}
I presume this line is causing the crash
wallNode?.physicsBody = SKPhysicsBody(rectangleOf: (wallNode?.frame.size)!)
as you are force unwrapping (!) the wallNode size however looking at your code you never assign it to anything like so
wallNode = self.childNode(withName: "wallNode") as? SKSpriteNode
or in the for loop.
Try this code in your for in loop that should avoid crashes and assigns your wall node.
for child in self.children where child.name == "wall" {
if let child = child as? SKSpriteNode {
wallNode = child // Try this
if let wallNode = wallNode { // safely unwrap wall node to avoid crashes
wallNode.physicsBody = SKPhysicsBody(rectangleOf: (wallNode.frame.size))
wallNode.physicsBody?.isDynamic = false
wallNode.physicsBody?.categoryBitMask = UInt32(wallCategory)
wallNode.physicsBody?.collisionBitMask = UInt32(playerCategory)
self.addChild(wallNode) // add wall node here instead if you are using your wallNode property
}
}
}
Hope this helps

Swift: Attemped to add a SKNode which already has a parent:

I know why I'm getting that error, but I can't figure out a way around it. I'm trying to have objects come appear and then be removed and the player should try to tap them before they're removed, but everytime the next node is about to appear it crashes. If i declare it inside its func then it all comes out but I can't tap on it...
Code:
let step = SKSpriteNode()
override func didMoveToView(view: SKView) {
physicsWorld.contactDelegate = self
backgroundColor = UIColor.feelFreeToColor()
self.color = self.randomNumbersInt(3)
self.showBars()
self.showScore()
let spawn = SKAction.runBlock {
//self.color = self.randomNumbersInt(3)
self.showSteps()
}
let delay = SKAction.waitForDuration(1.5)
let spawnDelay = SKAction.sequence([spawn , delay])
let spawnDelayForever = SKAction.repeatActionForever(spawnDelay)
self.runAction(spawnDelayForever)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
var location = touch.locationInNode(self)
if self.nodeAtPoint(location) == step {
self.score += 1
}
}
}
func showSteps() {
let createSteps = SKAction.moveByX(0, y: -self.frame.height - 30 , duration: 10)
let removeSteps = SKAction.removeFromParent()
step.color = colors[randomNumbersInt(3)]!
step.size = CGSize(width: 275, height: 30)
step.position = CGPoint(x: self.frame.width * 0.5, y: self.frame.height * 0.75)
step.physicsBody = SKPhysicsBody(rectangleOfSize: step.size)
step.physicsBody?.categoryBitMask = Config.PhysicBodyType.Steps.rawValue
step.physicsBody?.affectedByGravity = false
step.physicsBody?.dynamic = false
step.zPosition = 1
step.runAction(SKAction.repeatActionForever(SKAction.sequence([createSteps, removeSteps])))
addChild(step)
}
In your showSteps function, declare the step node inside it, not at the top of your code, and also give it a name:
func showSteps() {
let step = SKSpriteNode()
...
step.name = "step"
step.color = colors[randomNumbersInt(3)]!
// etc
}
In your touchesBegan method, you have this if statement:
if self.nodeAtPoint(location) == step {
self.score += 1
}
You want to remove that node that you have hit, but now you can just check the name property like so:
if self.nodeAtPoint(location)?.name == "step" {
self.nodeAtPoint(location)?.removeFromParent()
self.score += 1
}
Please note that I am not super fluent in Swift, but I think you will probably need the ? in your if statement, as it might not exist (such as if you didn't tap on a specific node). Somebody more familiar with Swift is free to correct me.

How can I require two collisions on one of my nodes before removing it from screen?

I have a collision based game with missiles and bombs. Everything works perfect right now with 1 collision and it removes the node from screen.
Although I want to be able to make bomb1 of my "bombs" harder to destroy so I would like to require it being hit twice. How can I do this?
Here are the bombs
func enemies() {
let bomb1 = SKSpriteNode(imageNamed: "Bomb1")
let bomb2 = SKSpriteNode(imageNamed: "bomb2")
let bomb3 = SKSpriteNode(imageNamed: "Bomb3")
let enemy = [bomb1, bomb2, bomb3]
// Enemy Physics
for bomb in enemy {
bomb1.size = CGSize(width: 55, height: 55)
bomb2.size = CGSize(width: 55, height: 70)
bomb3.size = CGSize(width: 30, height: 30)
bomb.physicsBody = SKPhysicsBody(circleOfRadius: bomb.size.width / 4)
bomb.physicsBody?.categoryBitMask = PhysicsCategory.enemy
bomb.physicsBody?.collisionBitMask = PhysicsCategory.missile | PhysicsCategory.airDefense
bomb.physicsBody?.contactTestBitMask = PhysicsCategory.missile | PhysicsCategory.airDefense
bomb.physicsBody?.affectedByGravity = false
bomb.physicsBody?.dynamic = true
bomb1.name = "enemy1"
bomb2.name = "enemy2"
bomb3.name = "enemy3"
}
Here is the function thats called when the bomb hits the missile.
func collisionWithMissile(enemy : SKSpriteNode, missile : SKSpriteNode) {
enemy.physicsBody?.dynamic = true
enemy.physicsBody?.affectedByGravity = true
missile.physicsBody?.affectedByGravity = true
enemy.physicsBody?.mass = 10.0
missile.physicsBody?.mass = 5.0
enemy.removeAllActions()
missile.removeAllActions()
enemy.removeFromParent()
missile.removeFromParent()
enemy.physicsBody?.contactTestBitMask = 0
enemy.physicsBody?.collisionBitMask = 0
enemy.name = nil
score++
scoreLbl.text = "\(score)"
}
This may help with the error Im getting
func didBeginContact(contact: SKPhysicsContact) {
if contact.bodyA.node != nil && contact.bodyB.node != nil {
let firstBody = contact.bodyA.node as! Bomb
let secondBody = contact.bodyB.node as! SKSpriteNode
// Bomb1 **********
if ((firstBody.name == "enemy1") && (secondBody.name == "missile")) {
collisionWithMissile(firstBody, missile: secondBody)
atomicExplosion(contact.bodyA.node!.position)
missileExplosion(contact.bodyB.node!.position)
}
You can subclass SKSpriteNode for your bombs and add a collision counter to this class. Inside your collisionWithMissile func you check the value of this counter and remove the bomb if a given value is reached otherwise you increase the counter.
Your subclass can look like this
class Bomb: SKSpriteNode {
var hitCount: Int
init(imageNamed: String, hitCount: Int) {
self.hitCount = hitCount
let texture = SKTexture(imageNamed: imageNamed)
super.init(texture: texture, color: UIColor.clearColor(), size: texture.size())
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The init method has hitCount as a parameter, so you can create easily Bombs with different strength. Your collisionWithMissile method could be like this. Just fill the if-else parts with your needed code.
func collisionWithMissile(enemy : Bomb, missile : SKSpriteNode) {
if enemy.hitCount <= 0 {
enemy.removeFromParent()
} else {
enemy.hitCount -= 1
}
}