0
votes

In my game, I use SKSprite. Some collisions are not detected. I did 10 tries, collisions are working well but about 25% of collisions that are supposed to be detected are not detected. I have NO idea why, I tried many things. Collisions are only with nodes of the same category.

I have no idea why randomly some collisions are not made when I can obviously see them, do you have any idea? Thanks for your help.

Here is the code of didBeginContact:

func didBeginContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody = contact.bodyA
    var secondBody: SKPhysicsBody = contact.bodyB

    if firstBody.categoryBitMask == secondBody.categoryBitMask {

            listContacts.append([firstBody.node!,secondBody.node!])
        }

    }
}

Here is the code of didEndContact:

func didEndContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody = contact.bodyA
    var secondBody: SKPhysicsBody = contact.bodyB

    if contact.bodyA.categoryBitMask == contact.bodyB.categoryBitMask {

        for i in listContacts{

            if (i.contains(firstBody.node!) && i.contains(secondBody.node!)){

                let findIndex = listContacts.indexOf { $0 == i }
                listContacts.removeFirst(findIndex!) 
            }
        }

    }

Finally when I declare a new SKSpriteNode I set this:

rectangle.physicsBody = SKPhysicsBody(rectangleOfSize: rectangle.size)
rectangle.physicsBody?.dynamic = true 
rectangle.physicsBody?.collisionBitMask = PhysicsCategory.None

usesPreciseCollisionDetection = true doesn't change anything so I don't use usePrecisionCollisionDetection

Every SKSpriteNode has his categoryBitmask and contactTestBitmask equal because only same SKSpriteNodes are supposed to collide.

Also:

physicsWorld.gravity = CGVectorMake(0, 0)
physicsWorld.contactDelegate = self

Finally here is a short video of my game if you want to understand easily what happens (problem of collisions are between rectangles) https://www.youtube.com/watch?v=-pbmKwQiE9U

2
Can you please post your touch functions? It looks like you tap in your video to remove the blocks, correct?Siriss
@Siriss you're right, but it's a HUGE function and I did many tests, I know it comes from the collision detection because listContacts doesn't have the connections so I don't think it will help unfortunately. Basically the touch function check which rectangles are next to it using listContacts then if there are minimum 3 next to each other of the same color, they will disappear.Oscar Falmer

2 Answers

0
votes

You seem to be checking if the categoryBitMask of body A equals body B.

if firstBody.categoryBitMask == secondBody.categoryBitMask {

        listContacts.append([firstBody.node!,secondBody.node!])
    }

}

This will only run an action if a node hits a node with the same categoryBitMask

You should be checking the collisionBitMasks to see if you have a collision, or you can check the name.

For an example using categoryBitMask you can do something like this:

func didBeginContact(contact: SKPhysicsContact) {

    var sprite: SKSpriteNode!

    if contact.bodyA.categoryBitMask == <your category bitmask> {
        sprite = contact.bodyA.node! as! SKSpriteNode
    }
    else if contact.bodyB.categoryBitMask == <your category bitmask> {
        sprite = contact.bodyB.node! as! SKSpriteNode
    }

    // Do something with sprite....
    // You can also create another sprite, and assign it to the other body, and perform functions on it, or both A and B.
    // It is good to have different functions you send can send the nodes to once you find out which ones they are.

}

You can do these checks to see which sprites are hitting each other.

0
votes

I just fixed it! The reason was that in the function "touchesEnded", I had a recursive function that was deleting bad connections in the listContacts!