-1

I am learning to make games on swift and spritekit, but stuck in one place. I managed to make the "enemy" and "bullet" removed after the first collision. Tell me, please, how to remove the "enemy" after a "bullet" hit it three times. I have been looking for an answer on the Internet for a long time, but without success.

import SpriteKit
import GameplayKit

class enemiesValue: SKSpriteNode {
    var health: Int = 3
}

class bulletValue: SKSpriteNode {
    var damage: Int = 1
}

class GameScene: SKScene, SKPhysicsContactDelegate {

var player: SKSpriteNode!
var touchLocation: CGPoint!
var timeSpawnEnemies: Timer!
var timeSpawnBullet: Timer!

struct PhysicsCategory {
    static let enemyCategory: UInt32 = 0x1 << 1
    static let bulletCategory: UInt32 = 0x1 << 0
}

override func didMove(to view: SKView) {
    self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
    self.physicsWorld.contactDelegate = self

    //playerAdd()
    timeSpawnEnemies = Timer.scheduledTimer(timeInterval: 2.75, target: self, selector: #selector(enemiesAdd), userInfo: nil, repeats: true)

}

@objc func enemiesAdd() {
    let enemyNode = enemiesValue(imageNamed: "enemy")
    let randomPos = GKRandomDistribution(lowestValue: -350, highestValue: 350)
    let pos = CGFloat(randomPos.nextInt())
    enemyNode.position = CGPoint(x: pos, y: 800)
    enemyNode.size = CGSize(width: 50, height: 50)
    enemyNode.yScale = 1.5
    enemyNode.xScale = 1.5

    //enemyNode.userData = ["health": 3]

    enemyNode.physicsBody = SKPhysicsBody(rectangleOf: enemyNode.size)
    enemyNode.physicsBody?.isDynamic = true
    enemyNode.physicsBody?.categoryBitMask = PhysicsCategory.enemyCategory
    enemyNode.physicsBody?.contactTestBitMask = PhysicsCategory.bulletCategory
    enemyNode.physicsBody?.collisionBitMask = 0

    self.addChild(enemyNode)

    let animDuration: TimeInterval = 16

    var actions = [SKAction]()

    actions.append(SKAction.move(to: CGPoint(x: pos, y: -800), duration: animDuration))
    actions.append(SKAction.removeFromParent())

    enemyNode.run(SKAction.sequence(actions))
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    //timeSpawnBullet = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(shoot), userInfo: nil, repeats: true)
    shoot()

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    //timeSpawnBullet.invalidate()
}

@objc func shoot() {
    let bullet = bulletValue(imageNamed: "bullet")
    bullet.size = CGSize(width: 75, height: 25)
    bullet.position = player.position

    bullet.physicsBody = SKPhysicsBody(rectangleOf: bullet.size)
    bullet.physicsBody?.isDynamic = true
    bullet.physicsBody?.categoryBitMask = PhysicsCategory.bulletCategory
    bullet.physicsBody?.contactTestBitMask = PhysicsCategory.enemyCategory
    bullet.physicsBody?.collisionBitMask = 0
    bullet.physicsBody?.usesPreciseCollisionDetection = true


    self.addChild(bullet)

    let animDuration: TimeInterval = 0.3

    var actions = [SKAction]()

    actions.append(SKAction.move(to: CGPoint(x: player.position.x, y: 800), duration: animDuration))
    actions.append(SKAction.removeFromParent())

    bullet.run(SKAction.sequence(actions))

}

func didBegin(_ contact: SKPhysicsContact) {
    let enemyBody: SKPhysicsBody
    let bulletBody: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        bulletBody = contact.bodyA
        enemyBody = contact.bodyB
    } else {
        bulletBody = contact.bodyB
        enemyBody = contact.bodyA
}

    if (enemyBody.categoryBitMask & PhysicsCategory.enemyCategory) != 0 && (bulletBody.categoryBitMask & PhysicsCategory.bulletCategory) != 0 {


        collisionElementsBullets(bulletNode: bulletBody.node as! SKSpriteNode)


        collisionElementsEnemies(enemyNode: enemyBody.node as! SKSpriteNode)

    }
}

func collisionElementsBullets(bulletNode: SKSpriteNode) {

    bulletNode.removeFromParent()

}

func collisionElementsEnemies(enemyNode: SKSpriteNode) {

    enemyNode.removeFromParent()

}

}
Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161
D.Denis
  • 3
  • 1
  • Hi Denis.. refer to some sites/locations where you tried to find solutions, how you implmented them (include the error code if needed). If its outside stackoverlfow you may consider pasting the essentials (differences in wording between yours and theirs). – ZF007 Dec 22 '18 at 11:35

1 Answers1

0
func collisionElementsEnemies(enemyNode: enemiesValue) 
{
   enemyNode.health = enemyNode.health - 1       

   if enemyNode.health == 0
   {
       enemyNode.removeFromParent()
   }
}

Since your enemiesValue (btw it should be capitalized and renamed. I would call it EnemySprite) is a descendant of SKSpriteNode you can put this type as a parameter type in collisionElementsEnemies. Then just reduce enemies health and remove the enemy from parent when its health drops to zero

You can call this method then like this:

collisionElementsEnemies(enemyNode: enemyBody.node as! enemiesValue)
Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161