-1

I'm building a function in which a random variable will choose 1 in 4 SKSpritenode in an array and assign itself to it. However, that randomline, although appear as expected on the screen, does not contain any physicsbody property so it cannot be collide with other node. Below is my code:

func line() {

        redLine = SKSpriteNode(imageNamed: "redline")
        blueLine = SKSpriteNode(imageNamed: "blueline")
        yellowLine = SKSpriteNode(imageNamed: "yellowline")
        greenLine = SKSpriteNode(imageNamed: "greenline")

        let lineArray = [redLine,blueLine,yellowLine,greenLine]
        // Add physics
        lineArray[0].physicsBody?.categoryBitMask = gamePhysics.RedLine
        lineArray[1].physicsBody?.categoryBitMask = gamePhysics.BlueLine
        lineArray[2].physicsBody?.categoryBitMask = gamePhysics.YellowLine
        lineArray[3].physicsBody?.categoryBitMask = gamePhysics.GreenLine

        for i in 0...3 {
            lineArray[i].physicsBody = SKPhysicsBody(circleOfRadius: 10)
            lineArray[i].physicsBody?.collisionBitMask = gamePhysics.RedBall | gamePhysics.BlueBall | gamePhysics.YellowBall | gamePhysics.GreenBall
            lineArray[i].physicsBody?.contactTestBitMask = gamePhysics.RedBall | gamePhysics.BlueBall | gamePhysics.YellowBall | gamePhysics.GreenBall
            lineArray[i].physicsBody?.affectedByGravity = false
            lineArray[i].physicsBody?.isDynamic = true
        }
        let randomLine:SKSpriteNode! = lineArray.randomElement()
        ...

        self.addChild(randomLine)
        ...

        randomLine.run(SKAction.sequence([moveLine,delay,removeLine]))
    }

So basically when the randomline collide with other node, nothing happen.

Here is my didBegin (contact) func:

func didBegin(_ contact: SKPhysicsContact) {
        let firstBody = contact.bodyA
        let secondBody = contact.bodyB

        if firstBody.categoryBitMask == gamePhysics.RedBall && secondBody.categoryBitMask == gamePhysics.RedLine || firstBody.categoryBitMask == gamePhysics.BlueBall && secondBody.categoryBitMask == gamePhysics.BlueLine || firstBody.categoryBitMask == gamePhysics.YellowBall && secondBody.categoryBitMask == gamePhysics.YellowLine || firstBody.categoryBitMask == gamePhysics.GreenBall && secondBody.categoryBitMask == gamePhysics.GreenLine {

            currentScore += 1
            secondBody.node?.removeFromParent()
            print("hit point")

        } else if firstBody.categoryBitMask == gamePhysics.RedLine && secondBody.categoryBitMask == gamePhysics.RedBall || firstBody.categoryBitMask == gamePhysics.BlueLine && secondBody.categoryBitMask == gamePhysics.BlueBall || firstBody.categoryBitMask == gamePhysics.YellowLine && secondBody.categoryBitMask == gamePhysics.YellowBall || firstBody.categoryBitMask == gamePhysics.GreenLine && secondBody.categoryBitMask == gamePhysics.GreenBall {

            currentScore += 1
            firstBody.node?.removeFromParent()
            print("hit point")

        }
    }

Any help would be appreciated! EDIT: Here is the ball func(). Maybe somehow the SKNode contain multiple categorybitmask and therefore, won't work?

func Ball() {

        ballNode = SKNode()
        redBall = SKSpriteNode(imageNamed: "redball")
        blueBall = SKSpriteNode(imageNamed: "blueball")
        yellowBall = SKSpriteNode(imageNamed: "yellowball")
        greenBall = SKSpriteNode(imageNamed: "greenball")

        let ballArray = [redBall,blueBall,yellowBall,greenBall]
        ...

        // Add physics
        ballArray[0].physicsBody?.categoryBitMask = gamePhysics.RedBall
        ballArray[1].physicsBody?.categoryBitMask = gamePhysics.BlueBall
        ballArray[2].physicsBody?.categoryBitMask = gamePhysics.YellowBall
        ballArray[3].physicsBody?.categoryBitMask = gamePhysics.GreenBall

        for i in 0...3 {
            ballArray[i].physicsBody = SKPhysicsBody(circleOfRadius: 20)
            ballArray[i].physicsBody?.collisionBitMask = gamePhysics.RedLine | gamePhysics.BlueLine | gamePhysics.YellowLine | gamePhysics.GreenLine
            ballArray[i].physicsBody?.contactTestBitMask = gamePhysics.RedLine | gamePhysics.BlueLine | gamePhysics.YellowLine | gamePhysics.GreenLine
            ballArray[i].physicsBody?.affectedByGravity = false
            ballArray[i].physicsBody?.isDynamic = false
        }

        ballNode.addChild(redBall)
        ballNode.addChild(greenBall)
        ballNode.addChild(yellowBall)
        ballNode.addChild(blueBall)

        self.addChild(ballNode)
    }

UPDATE 2: Here is a struct where i store my categorybitmask:

struct gamePhysics {

    static let RedBall : UInt32 = 0x1 << 1
    static let BlueBall : UInt32 = 0x1 << 2
    static let GreenBall : UInt32 = 0x1 << 3
    static let YellowBall : UInt32 = 0x1 << 4
    static let RedLine : UInt32 = 0x1 << 5
    static let BlueLine : UInt32 = 0x1 << 6
    static let GreenLine : UInt32 = 0x1 << 7
    static let YellowLine : UInt32 = 0x1 << 8
}
Khoi Le
  • 3
  • 4

2 Answers2

0

Did you remember setting the contact delegate inside your scene? Place this line of code inside didMove(to:):

self.physicsWorld.contactDelegate = self

If this don't solve the issue, I would make the if conditions inside didBegin more explicit using parentheses between the && and || statements.

Looking to the rest of the code I can not see what else could be wrong, what you did should work. Are the print("hit point") you placed inside the if statements been reached?

Maria
  • 134
  • 6
  • Hi, yes i did include the self.physicsWorld.contactDelegate = self but it doesn't work. And the print("hit point") does not run at all, so i think there something preventing the code to go into that if statement... Initially i thought because i put the "randomline" inside the addChild fuction. However, when i tried to use the addChild method for a single line it still did not solve anything... Maybe the line somehow has been assign the physics body yet? The categorybit mask does not work? – Khoi Le May 08 '20 at 02:53
  • What are the values of the categoryBitMasks? – Maria May 08 '20 at 12:10
  • I store it in a struct as in the edit i make of my question. It's a UInt32 value. – Khoi Le May 08 '20 at 15:32
0

OMG i found the answer to my question. The reason for the value of the categorybitmask to return "nil" was because i actually assign the node to categorybitmask before specified its physicsbody. Move the line down a few line and everything is solved!

Khoi Le
  • 3
  • 4