2
votes

I have a problem with the following sprite kit code. I'm trying to detect when a flying ball is colliding with a line. However nothing happens when the two collide. However when the ball hits the edge of the scene, the following is printed out:

contact 1 bitmask1: 4294967295 bitmask2: 4294967295

Problem 1: Why aren't the line and ball collisions being detected? Problem 2: Why are both of the bitmask the same on edge collision? I can't work with the bodies if I don't know which is which.

struct PhysicsCategory {
    static let None      : UInt32 = 0
    static let All       : UInt32 = UInt32.max
    static let Ball      : UInt32 = 0b1       // 1
    static let Line      : UInt32 = 0b10      // 2
    static let Shape     : UInt32 = 0b100     // 3 or 4?
}
override func didMoveToView(view: SKView) {
    /* Setup your scene here */       
    physicsWorld.contactDelegate = self

    self.physicsBody = SKPhysicsBody(edgeLoopFromRect: view.frame);
    self.physicsWorld.gravity = CGVectorMake(0.0, 0.0);

    let ball = SKShapeNode(circleOfRadius: 5)
    ball.fillColor = UIColor.whiteColor()
    ball.strokeColor = UIColor.whiteColor()
    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.size.width/2)
    ball.physicsBody?.velocity = CGVector(dx: 200.0, dy: 200.0)
    ball.position = CGPoint(x: view.bounds.width/2, y:view.bounds.height/2)
    ball.physicsBody?.friction = 0.0;
    ball.physicsBody?.restitution = 1.0;
    ball.physicsBody?.linearDamping = 0.0;
    ball.physicsBody?.allowsRotation = false
    ball.physicsBody?.applyImpulse(CGVector(dx:CGFloat(100), dy:CGFloat(100)));
    ball.physicsBody?.categoryBitMask = PhysicsCategory.Ball
    ball.physicsBody?.dynamic = true
    ball.physicsBody?.contactTestBitMask = PhysicsCategory.Line
    ball.physicsBody?.collisionBitMask = PhysicsCategory.Line
    self.addChild(ball)
}

override func touchesMoved(touches: NSSet, withEvent event: UIEvent) { /* Called when a touch begins */

    touch = touches.anyObject() as UITouch!

    var linePhysicsBody = SKPhysicsBody()
    linePhysicsBody.categoryBitMask = PhysicsCategory.Line
    linePhysicsBody.contactTestBitMask = PhysicsCategory.Ball
    linePhysicsBody.collisionBitMask = PhysicsCategory.Ball
    linePhysicsBody.dynamic = false
    linePhysicsBody.usesPreciseCollisionDetection = true

    lineNode = SKShapeNode()
    lineNode.physicsBody = linePhysicsBody
    lineNode.name = "drawingLine"
    lineNode.path = linePath
    lineNode.lineWidth = 5.0
    lineNode.strokeColor = UIColor.redColor()
    lineNode.glowWidth = 1.0

    self.addChild(lineNode)
}

func didBeginContact(contact: SKPhysicsContact) {

    println("contact \(++tempCounter)")
    println("bitmask1: \(contact.bodyA.categoryBitMask)")
    println("bitmask2: \(contact.bodyA.categoryBitMask)")
}
1

1 Answers

1
votes

For Problem 1:

your line physics body has a size of 0. You have to create at least a small rectangle which represents the line. Otherwize there is no collision.

For Problem 2:

func didBeginContact(contact: SKPhysicsContact) {

    println("contact \(++tempCounter)")
    println("bitmask1: \(contact.bodyA.categoryBitMask)")
    println("bitmask2: \(contact.bodyA.categoryBitMask)")
}

There's a typo. You must use bodyB for bitmask2