Certain physicsBody collisions not registering

345 Views Asked by At

I'm practising what I have learnt in swift so far and I'm trying to make a simple game where a ball bounces on a platform that you can move. I have a floor underneath the platform, which will eventually allow the game to end. At the moment, the ball can bounce off the floor, and the barrier I have put around the scene, but just passes through the platform that you can move across the screen. Apart from category names, the code for the floor and platform are basically the same, I can't tell why this isn't working. Here is my code:

class GameScene: SKScene, SKPhysicsContactDelegate {


    let ballGroup: UInt32 = 0b001
    let platformGroup: UInt32 = 0b010
    let floorGroup: UInt32 = 0b100
    let sceneEdgeGroup : UInt32 = 0b101

    var platform = SKShapeNode()
    var floor = SKShapeNode()
    var ball = SKShapeNode()

    var i = 0

    override func didMoveToView(view: SKView) {

        self.size = view.bounds.size
        self.physicsWorld.contactDelegate = self
        self.physicsWorld.gravity = CGVectorMake(0, -5)

        let physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
        self.physicsBody = physicsBody
        self.physicsBody?.categoryBitMask = sceneEdgeGroup
        self.physicsBody?.friction = 0
        self.physicsBody?.restitution = 1


        platform = SKShapeNode(rectOfSize: CGSizeMake(100, 15))
        platform.fillColor = SKColor.redColor()

        platform.position = CGPointMake(CGRectGetMidX(self.frame)  -  (CGRectGetMidX(self.frame)), CGRectGetMidY(self.frame) * 0.4)
        platform.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(100, 15))
        platform.physicsBody?.dynamic = false
        platform.physicsBody?.allowsRotation = false

        platform.physicsBody?.categoryBitMask = platformGroup
        platform.physicsBody?.friction = 0


        self.addChild(platform)


        floor = SKShapeNode(rectOfSize: CGSizeMake(self.frame.size.width, 200))
        floor.fillColor = SKColor.blueColor()
        floor.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - CGRectGetMidY(self.frame))
        floor.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, 200))
        floor.physicsBody?.dynamic = false

        floor.physicsBody?.categoryBitMask = floorGroup
        floor.physicsBody?.friction = 0

        self.addChild(floor)


        ball = SKShapeNode(circleOfRadius: 5)
        ball.fillColor = SKColor.blackColor()
        ball.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) * 1.5 )
        ball.physicsBody = SKPhysicsBody(circleOfRadius: 5)
        ball.physicsBody?.dynamic = true
        ball.physicsBody?.categoryBitMask = ballGroup
        ball.physicsBody?.collisionBitMask = platformGroup
        ball.physicsBody?.collisionBitMask = floorGroup
        ball.physicsBody?.collisionBitMask = sceneEdgeGroup

        ball.physicsBody?.contactTestBitMask = floorGroup
        ball.physicsBody?.contactTestBitMask = platformGroup
        ball.physicsBody?.contactTestBitMask = sceneEdgeGroup

        ball.physicsBody?.friction = 0
        ball.physicsBody?.restitution = 0
        ball.physicsBody?.mass = 0.5
        ball.physicsBody?.linearDamping = 0
        ball.physicsBody?.allowsRotation = false

        self.addChild(ball)

        //start ball movement
        ball.physicsBody?.applyImpulse(CGVectorMake(-5, 0))
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

        let moveAction1 = SKAction.moveByX((self.frame.width) , y: 0, duration: 1)
        let moveAction2 = SKAction.moveByX((-self.frame.width) , y: 0, duration: 1)


        if(i == 0){
            platform.runAction(moveAction1)
            i++
        }else if (i == 1){
            platform.runAction(moveAction2)
            i = 0
        }
    }


    func didBeginContact(contact: SKPhysicsContact) {
        if(contact.bodyB.categoryBitMask == ballGroup && contact.bodyA.categoryBitMask == floorGroup || (contact.bodyA.categoryBitMask == ballGroup && contact.bodyB.categoryBitMask == floorGroup)){

            //this contact works
           // ball.physicsBody?.restitution = 0.5
            //ball.physicsBody?.applyImpulse(CGVectorMake(0, 350))

        }

        if(contact.bodyB.categoryBitMask == ballGroup && contact.bodyA.categoryBitMask == platformGroup || (contact.bodyA.categoryBitMask == ballGroup && contact.bodyB.categoryBitMask == platformGroup)){

            //this contact doesn't work
            //should make ball bounce
            ball.physicsBody?.applyImpulse(CGVectorMake(0, 300))
        }

    }

}

1

There are 1 best solutions below

2
On BEST ANSWER

Currently you overwrite the Bitmasks:

    ball.physicsBody?.contactTestBitMask = floorGroup
    ball.physicsBody?.contactTestBitMask = platformGroup
    ball.physicsBody?.contactTestBitMask = sceneEdgeGroup

You have to combine them:

    ball.physicsBody?.contactTestBitMask = floorGroup | platformGroup | sceneEdgeGroup

Same here:

    ball.physicsBody?.collisionBitMask = platformGroup
    ball.physicsBody?.collisionBitMask = floorGroup
    ball.physicsBody?.collisionBitMask = sceneEdgeGroup