3
votes

I am having some trouble detecting the collision of two objects when i shoot from my cannon. The goal is to shoot a bullet from it and remove as soon as it colides with the obstacle. It seems there is no collision going on at all in the game, since i cannot receive the "Collision" message i set. Take a look at the following code:

class GameScene: SKScene, SKPhysicsContactDelegate {


enum BodyType: UInt32 {
    case bullet = 1
    case line = 2
    case breaker = 4
}

i've enumerated the components so i can set them in the category Bitmask. After that, i did a setup from shooting when a touch begins.

 override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

    /* Called when a touch begins */

    for touch in (touches as! Set<UITouch>) {

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

    bullet.position = self.shooterTriangle.position

    var actionRotate = SKAction.rotateToAngle(CGFloat(2 * -M_PI), duration: NSTimeInterval(0.1))

    let actionMove = SKAction.moveTo(CGPoint(x: 500, y: size.height * 0.5), duration: NSTimeInterval(0.5))

    let removeBullet = SKAction.removeFromParent()

    bullet.runAction(SKAction.sequence([actionRotate]))

    bullet.runAction(SKAction.sequence([actionMove, removeBullet]))

    addChild(bullet)

        // Bullet Physics Start ****

        bullet.physicsBody? = SKPhysicsBody(circleOfRadius: bullet.size.width/2.0)

        bullet.physicsBody?.dynamic = true
        bullet.physicsBody?.affectedByGravity = false
        bullet.physicsBody?.allowsRotation = false
        bullet.physicsBody?.categoryBitMask = BodyType.bullet.rawValue
        bullet.physicsBody?.contactTestBitMask = BodyType.line.rawValue
        bullet.physicsBody?.collisionBitMask = BodyType.line.rawValue

    }
}

Then i`ve add the line i want the bullet to colide with in a loadGameComponents function...

func loadGameComponents() {

//Load line....

    let line = SKSpriteNode(imageNamed: "Line_1.png")

    line.position = CGPoint(x: size.width * 0.95, y: size.height * (2.0))

    addChild(line)

    var actualSpeedDuration = 2.2

    let lineActionMove = SKAction.moveTo(CGPoint(x: size.width * 0.95, y: size.height * 0.6), duration: NSTimeInterval(actualSpeedDuration))

    line.runAction(SKAction.sequence([lineActionMove]))

    // Line Physics starts! *****

    line.physicsBody? = SKPhysicsBody(rectangleOfSize: CGSize(width: line.size.width, height: line.size.height))

    line.physicsBody?.dynamic = false
    line.physicsBody?.affectedByGravity = false
    line.physicsBody?.allowsRotation = false
    line.physicsBody?.categoryBitMask = BodyType.line.rawValue
    line.physicsBody?.contactTestBitMask = BodyType.bullet.rawValue
    line.physicsBody?.collisionBitMask = 0

Finally, i've defined the contactDelegate = self in my didLoad function and included the didBeginContact method

func didBeginContact(contact: SKPhysicsContact) {
    println("Contact!!!")
}

I am not receiving the message at all, but i am not sure what is going wrong!

Thanks for the patience! :)

1
try using the checkPhysics() function in this answer - stackoverflow.com/questions/36570859/… when your contact/collisions aren't working as you think they should. It goes through all nodes in the scene and compares their collision & contactTest bitMasks with every other node to print out what collisions and contacts will occur.Steve Ives

1 Answers

2
votes

Looks like the main problem is that i used to place the optional indicator (?) when declaring the physics body of an sprite. correction should be made in this lines...

line.physicsBody? = SKPhysicsBody(rectangleOfSize: CGSize(width: line.size.width, height: line.size.height))

bullet.physicsBody? = SKPhysicsBody(circleOfRadius: bullet.size.width/2.0)

Removing them solved my problem :)

I also included the view.showPhysics = true in my didMoveToView method so it is easy to see the boundaries between the sprites.