0

I'm writing SpriteKit app for Mac OS. I have two objects (projectile and a monster):

let suric = SKSpriteNode(imageNamed: "projectile.png")
suric.position = player.position
suric.physicsBody = SKPhysicsBody(circleOfRadius: self.size.width / 2)
suric.physicsBody?.categoryBitMask = Detection.suric
suric.physicsBody?.collisionBitMask = Detection.no
suric.physicsBody?.contactTestBitMask = Detection.monster
suric.physicsBody?.usesPreciseCollisionDetection = true
suric.physicsBody?.dynamic = true

let offset = location - suric.position 
if offset.x < 0 {
    return
}    
addChild(suric)   
let direc = offset.normalized()
let shoot = direc * 1000
let dest = shoot + suric.position        
let move = SKAction.moveTo(dest, duration: 2.0)
let stop = SKAction.removeFromParent()
suric.runAction(SKAction.sequence([move, stop]))

Monster code:

let monster = SKSpriteNode(imageNamed: "monster.png")

let y = random(min: monster.size.height / 2, size.height - monster.size.height)
monster.position = CGPoint(x: self.size.width + monster.size.width / 2, y: y)
monster.physicsBody = SKPhysicsBody(rectangleOfSize: monster.size)
monster.physicsBody?.usesPreciseCollisionDetection = true
monster.physicsBody?.categoryBitMask = Detection.monster
monster.physicsBody?.contactTestBitMask = Detection.suric
monster.physicsBody?.collisionBitMask = Detection.no
monster.physicsBody?.dynamic = true
addChild(monster)     
let duration = random(min: 2.0, 4.0)
let move = SKAction.moveTo(CGPoint(x: -monster.size.width / 2, y: y), duration: NSTimeInterval(duration))
let done = SKAction.removeFromParent()     
monster.runAction(SKAction.sequence([move, done]))

Detection structure:

struct Detection {
    static var no : UInt32 = 0
    static var all : UInt32 = UInt32.max
    static var monster : UInt32 = 0b1
    static var suric : UInt32 = 0b10
}

And then I try to check if there was a contact between these 2 objects:

func didBeginContact(contact: SKPhysicsContact) {
    var first : SKPhysicsBody
    var second : SKPhysicsBody
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        first = contact.bodyA
        second = contact.bodyB
    }
    else {
        first = contact.bodyB
        second = contact.bodyA
    }

    if (first.categoryBitMask & Detection.monster != 0) && (second.categoryBitMask & Detection.suric != 0) {
        suricHit(first.node as? SKSpriteNode, monster: second.node as? SKSpriteNode)
    }
}

It works even if they didn't actually make a contact. E.g., the projectile is near the top of the window, the monster is at the bottom, but this function works.

EDIT:

I added this code to didBeginContact:

let nodeA = (first.node as! SKSpriteNode)
let nodeB = (second.node as! SKSpriteNode)  
println("\(nodeA.position)\t\(nodeA.size)")
println("\(nodeB.position)\t\(nodeB.size)")
println((contact.contactPoint))
println()

The example of out:

(510.201293945312, 285.025665283203)    (54.0, 80.0)
(532.54345703125, 378.878845214844) (20.0, 20.0)
(852.469543457031, 530.415222167969)

As you can see, the x position of nodes are 510 and 532, but the contact x point is 852. I just have no idea how and why. Does anybody have a solution?

pomo_mondreganto
  • 2,028
  • 2
  • 28
  • 56
  • possible duplicate of [beginner swift sprite kit - node collision detection help (SKPhysicsContact)](http://stackoverflow.com/questions/26270504/beginner-swift-sprite-kit-node-collision-detection-help-skphysicscontact) – sangony Apr 21 '15 at 12:09
  • @sangony, the problem is different. In my case, the function is called even if there was no actual contact between two nodes – pomo_mondreganto Apr 21 '15 at 14:22

1 Answers1

0

You're missing an extra set of parenthesis in the if statement.

if ((first.categoryBitMask & Detection.monster != 0) && (second.categoryBitMask & Detection.suric != 0)) {
    suricHit(first.node as? SKSpriteNode, monster: second.node as? SKSpriteNode)
}

PS I followed this tutorial and put my project on GitHub, check it out!

Alex Chesters
  • 3,380
  • 5
  • 19
  • 27