Flinigan
Flinigan

Reputation: 105

Not detecting collision

I'm getting some difficulty detecting collision in my SpriteKit Game. I simply want to detect collision between the missiles and the enemies and boats.

I have the ColliderType:

struct ColliderType {
static let Boat: UInt32 = 1
static let Enemy: UInt32 = 2
static let Wall: UInt32 = 3
static let Bullet: UInt32 = 4

}

class GameplayScene: SKScene, SKPhysicsContactDelegate {

var player = SKSpriteNode()
var enemy = SKSpriteNode()
var boat = SKSpriteNode()
var missile = SKSpriteNode()

The didBegin contact:

func didBegin(_ contact: SKPhysicsContact) {

    var firstBody = SKPhysicsBody()
    var secondBody = SKPhysicsBody()

    if contact.bodyA.node?.name == "Missile" {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    if firstBody.node?.name == "Missile" && secondBody.node?.name == 
"Enemy" {
        incrementScore()
        secondBody.node?.removeFromParent()
    } else if firstBody.node?.name == "Missile" && 
secondBody.node?.name == "Boat" {
        incrementScore()
    }

}

I have also added physicsBodies to all the relevant spritenodes:

func fireMissile() {
    let missile = SKSpriteNode(color: .yellow, size: CGSize(width: 20, 
    height: 5))
    missile.name = "Missile"
    missile.position = CGPoint(x: player.position.x + 28, y: 
    player.position.y + 10)
    missile.zPosition = 2
    missile.physicsBody = SKPhysicsBody(rectangleOf: missile.size)
    missile.physicsBody?.isDynamic = false
    missile.physicsBody?.categoryBitMask = ColliderType.Bullet
    missile.physicsBody?.collisionBitMask = ColliderType.Enemy | 
    ColliderType.Boat
    missile.physicsBody?.contactTestBitMask = ColliderType.Enemy | 
    ColliderType.Boat


    self.addChild(missile)

}


func createEnemies() {
    let enemy = SKSpriteNode(imageNamed: "Enemy1")
    enemy.name = "Enemy"
    enemy.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.size.height 
/ 2)
    enemy.physicsBody?.categoryBitMask = ColliderType.Enemy
    enemy.physicsBody?.affectedByGravity = false
    enemy.physicsBody?.isDynamic = false
    enemy.zPosition = 3

    enemy.position.y = self.frame.height + 100
    enemy.position.x = CGFloat.randomBetweenNumbers(firstNum: -347.5, 
    secondNum: -85)


    self.addChild(enemy)

}


func createBoat() {
    let boat = SKSpriteNode(imageNamed: "Boat")
    boat.name = "Boat"
    boat.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    boat.physicsBody = SKPhysicsBody(circleOfRadius: boat.size.height / 
    2)
    boat.physicsBody?.categoryBitMask = ColliderType.Boat
    boat.physicsBody?.affectedByGravity = false
    boat.physicsBody?.isDynamic = false
    boat.zPosition = 3

    boat.position.y = self.frame.height + 100
    boat.position.x = CGFloat.randomBetweenNumbers(firstNum: 0, 
    secondNum: 0)


    self.addChild(boat)


}

Upvotes: 0

Views: 58

Answers (1)

Steve Ives
Steve Ives

Reputation: 8134

Firstly, some of your categories are wrong:

static let Wall: UInt32 = 3
static let Bullet: UInt32 = 4

This effectively defines Wall as being both a Boat and an Enemy. Change them to:

static let Wall: UInt32 = 4
static let Bullet: UInt32 = 8

(Categories should always be unique powers of 2 - 1, 2, 4, 8, 16 etc).

The rest looks ok, so try that and let us know if it’s working.

Edit:

OK - just noticed that all of your physics bodies have their isDynamic property set to false - this means that, among other things, the body will not trigger contacts. so if you want missile to generate contacts with either enemy or boat, then either missile should be dynamic or both enemy and boat should be dynamic (only 1 of the 2 objects involved in a contact needs to by dynamic).

Upvotes: 3

Related Questions