2

So I made some adjustments to the ball in my game and to avoid an unwrapping optional value error, I commmented out the following

//didMoveToView
    self.physicsWorld.gravity = CGVectorMake(0, 0)
    self.physicsWorld.contactDelegate = self
    let fieldBody = SKPhysicsBody.init(edgeLoopFromRect: self.frame)
    self.physicsBody = fieldBody
    self.physicsBody!.affectedByGravity = false
    self.physicsBody!.usesPreciseCollisionDetection = true
    self.physicsBody!.dynamic = true
    self.physicsBody!.mass = 0
    self.physicsBody!.friction = 0
    self.physicsBody!.linearDamping = 0
    self.physicsBody!.angularDamping = 0
    self.physicsBody!.restitution = 1
    self.physicsBody!.categoryBitMask = CollisionTypes.Floor.rawValue
    self.physicsBody!.contactTestBitMask = CollisionTypes.Ball.rawValue

    // Prepare the ball - physics engine.
    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
    ball.physicsBody!.affectedByGravity = true
    ball.physicsBody!.restitution = 0.8
    ball.physicsBody!.linearDamping = 0
    ball.physicsBody!.friction = 0.3
    ball.physicsBody!.dynamic = true
    ball.physicsBody!.mass = 0.5
    ball.physicsBody!.allowsRotation = true
    ball.physicsBody!.categoryBitMask = CollisionTypes.Ball.rawValue
    ball.physicsBody!.contactTestBitMask = CollisionTypes.Floor.rawValue
    ball.physicsBody!.collisionBitMask = CollisionTypes.Floor.rawValue
}

I did that, my game launced but as soon as toucheBegan, the same error popped up. I do not know how to get around all of these unrwapping errors. I am new to swift and not sure how i should adjust thse physics. My contactBegin looks this:

func didBeginContact(contact: SKPhysicsContact) {
    let bitMaskAAndB = contact.bodyA.categoryBitMask == CollisionTypes.Floor.rawValue &&
                contact.bodyB.categoryBitMask == CollisionTypes.Ball.rawValue
    let ballAndBoardMask = CollideType.Ball.toMask() | boards.usedCollideMasks

    // ball and board, handle it by board delegate
    if bitMaskAAndB | ballAndBoardMask == ballAndBoardMask {

        let boardNode: SKNode! = contact.bodyA.categoryBitMask == CollideType.Ball.toMask() ? contact.bodyB.node : contact.bodyA.node
        let board = boardNode.bind as! BoardDelegate
        board.didBeginContact(boardNode, ball: ball, contact: contact, game: self)
    }

    // ball and ceil => stop game
    else if bitMaskAAndB == CollideType.toMask([.Ball, .Ceil]) {
        stopGame()
    }

    // ball and floor => stop game add explosion or fall off screen
    else if bitMaskAAndB == CollideType.toMask([.Ball, .Floor]) {
        stopGame()
    }
}
func didEndContact(contact: SKPhysicsContact) {

    let ballAndBoardMask = CollideType.Ball.toMask() | boards.usedCollideMasks

    // ball and board, handle it by board delegate
    if contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask | ballAndBoardMask == ballAndBoardMask {

        let boardNode: SKNode! = contact.bodyA.categoryBitMask == CollideType.Ball.toMask() ? contact.bodyB.node : contact.bodyA.node
        let board = boardNode.bind as! BoardDelegate
        board.didEndContact(boardNode, ball: ball, contact: contact, game: self)
    }

}

EDIT: I set up my physics world to the suggestions you made and adjusted my didBeginContact fun however with the following code, I am getting multiple errors regarding: cannot convert value of type bool to UInt32.

PS. thank you for your help and patience, this is all new terminology and Im doing my best to understand. :)

N. Howey
  • 119
  • 7
  • 3
    Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](http://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – Eiko Jul 09 '16 at 11:12
  • Just use optional binding and you'll be fine. Or you can use optional chaining. Means, when an underlying value might be nil, then you should access it in safe way using one of the methods above. Or you can just check if variable != nil. – Whirlwind Jul 09 '16 at 19:33

1 Answers1

2

I don't know your CollideType class or declaration, so my code below explain to you how to build a correct physicsWorld and physicsBody to don't have issues during the collisions.

But first: we're going to be using the categoryBitMask, contactTestBitMask and collisionBitMask properties in their fullest for this project, because we have very precise rules that make the project work:

  • categoryBitMask is a number defining the type of object this is for considering collisions.

  • collisionBitMask is a number defining what categories of object this node should collide with.

  • contactTestBitMask is a number defining which collisions we want to be notified about.

SpriteKit expects these three bitmasks to be described using a UInt32.Your bitmasks should start at 1 then double each time.

The code:

class GameScene: SKScene, SKPhysicsContactDelegate {
    var ball: Ball!
    let ballSpeedX = CGFloat(500)
    enum CollisionTypes: UInt32 {
        case Field = 1
        case Ball = 2
    }
    override func didMoveToView(view: SKView) {
        // ball
        ball = Ball(imageNamed:"colorBall.png")
        ball.position = CGPointMake(self.ball.frame.size.width,self.ball.frame.size.height)

        // Prepare the world - physics engine.
        self.physicsWorld.gravity = CGVectorMake(0, -6)
        self.physicsWorld.contactDelegate = self
        let fieldBody = SKPhysicsBody.init(edgeLoopFromRect: self.frame)
        self.physicsBody = fieldBody
        self.physicsBody!.affectedByGravity = false
        self.physicsBody!.usesPreciseCollisionDetection = true
        self.physicsBody!.dynamic = true
        self.physicsBody!.mass = 0
        self.physicsBody!.friction = 0
        self.physicsBody!.linearDamping = 0
        self.physicsBody!.angularDamping = 0
        self.physicsBody!.restitution = 1
        self.physicsBody!.categoryBitMask = CollisionTypes.Field.rawValue
        self.physicsBody!.contactTestBitMask = CollisionTypes.Ball.rawValue

        // Prepare the ball - physics engine.
        ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
        ball.physicsBody!.affectedByGravity = true
        ball.physicsBody!.restitution = 0.8
        ball.physicsBody!.linearDamping = 0
        ball.physicsBody!.friction = 0.3
        ball.physicsBody!.dynamic = true
        ball.physicsBody!.mass = 0.5
        ball.physicsBody!.allowsRotation = true
        ball.physicsBody!.categoryBitMask = CollisionTypes.Ball.rawValue
        ball.physicsBody!.contactTestBitMask = CollisionTypes.Field.rawValue
        ball.physicsBody!.collisionBitMask = CollisionTypes.Field.rawValue

        //ball.physicsBody!.categoryBitMask = CollideType.Ball.toMask()
        //ball.physicsBody!.collisionBitMask = CollideType.toMask([.Scene, .Ceil, .Floor]) | boards.usedCollideMasks
        //ball.physicsBody!.contactTestBitMask = CollideType.toMask([.Scene, .Ceil, .Floor]) | boards.usedCollideMasks
        ball.hidden = false
        self.addChild(ball)
    }
    func didBeginContact(contact: SKPhysicsContact) {
        if (contact.bodyA.categoryBitMask == CollisionTypes.Field.rawValue &&
            contact.bodyB.categoryBitMask == CollisionTypes.Ball.rawValue) {
            print("contact between field and ball")
        }
    }
}

As you can see, the first important thing is to prepare the physicsWorld (track the boundaries within wich your physics must work), assign it a category and all the other parameters need to interact with the other objects. Then you build the physicsBody of your object , in this case the ball.

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
  • Thank you for your response I detailed explanation. I have went over it and tried to implement it with a slight problem. I updated my question! thanks. ps. I owe you one! Can I buy you a beer? ;) – N. Howey Jul 10 '16 at 07:19
  • I've seen, the problem is always CollideType, I don't know what is , it's impossible for everyone if you don't know CollideType sources. For example CollisionTypes is a struct and you can see it's declaration in my example. I think you must proceed step by step everytime to understand what happened otherwise you risk to have too many crashes.. – Alessandro Ornano Jul 10 '16 at 07:28
  • If you have solved and understanded the concept about collisions so close the question and open another thread where you report your CollideType source and the exact errors, because this is another question.Thank you. – Alessandro Ornano Jul 10 '16 at 07:30
  • 1
    Good point, that is a seperate question. Thank you for your great explanation, I am learning a lot. I have opened marked this solved and opened a seperate one. http://stackoverflow.com/questions/38289783/collide-type-source-error-spritekit-swift-game – N. Howey Jul 10 '16 at 07:47
  • Good , I' will try to take a look. – Alessandro Ornano Jul 10 '16 at 07:48