cad71
cad71

Reputation: 33

iOS How to check if three sprites make contact

I know how two check if two sprites make contact in spritekit (using contact.bodyA and contact.bodyB). Can someone explain how i can check if three sprite make contact with each other? (Three square sprites that make contact because they are stacked on top of each other for example)

Thx

Edit: I've figured out that it's possible to use allContactedBodies, to find all contacts to one body. See code below. But the for loop gets an error, for some reason. Error: '[AnyObject]?' does not have a member named 'Generator' Does anyone how to fix this?

func didBeginContact(contact:SKPhysicsContact) {
    var node1:SKNode = contact.bodyA.node!
    var node2:SKNode = contact.bodyB.node!
    if ( node1.physicsBody?.categoryBitMask == node2.physicsBody?.categoryBitMask ) {
        let bodies = node1.physicsBody?.allContactedBodies()
        if bodies?.count > 3 {
            NSLog("%i", bodies!.count)
            for potentialBody : AnyObject in bodies {
                if let body = potentialBody as? SKPhysicsBody {
                    body.node?.removeFromParent()
                }
            }
        }
    }
}

Upvotes: 3

Views: 625

Answers (3)

cad71
cad71

Reputation: 33

This is better version:

func didBeginContact(contact: SKPhysicsContact) {
    let bodies = contact.bodyA.node!.physicsBody!.allContactedBodies()
    if (bodies.count > 1) {
        for body in bodies {
            if body.categoryBitMask == contact.bodyA.categoryBitMask {
                body.node!?.removeFromParent()
            }
        }
    }
}

Upvotes: 0

cad71
cad71

Reputation: 33

squareThe following code will work, thanks for all the help:

func didBeginContact(contact:SKPhysicsContact) {
    let bodies = contact.bodyA.node?.physicsBody?.allContactedBodies()
    if ( bodies!.count > 1 ) {
        NSLog("%i", bodies!.count)
        for body:AnyObject in bodies ?? [] {
            if body.categoryBitMask == squareCategory {
                body.node??.removeFromParent()
            }
        }
    }
}

Upvotes: 0

jonogilmour
jonogilmour

Reputation: 673

Consider this untested code:

func didBeginContact(contact:SKPhysicsContact) {
    let bodies = contact.bodyA.node!.physicsBody!.allContactedBodies()
    if bodies.count > 1 {
        NSLog("%i", bodies!.count)
        for body:SKPhysicsBody in bodies {
            body.node!.removeFromParent()
        }
    }
}

First off, if the bodies are in contact, their bitmasks will at least overlap, so there isn't any need to check the bitmasks (unless you want to be as specific as possible). Also, if you assume that contact.bodyA.node is not nil, then you can assume that it has a physicsBody because it is being contacted (which is only possible with a physicsBody).

Also, you are interested in three (or more?) bodies coming into contact, so you only need to check for more than one body coming into contact with a single body, so the check for > 1 means "if there are more than two bodies (eg three) involved in this contact then...".

Last of all, bodies contains an array of SKPhysicsBody objects, with no nil values (if they are nil, then they are not involved in this collision), so it is safe to cast any object in bodies to SKPhysicsBody. You can assume the physicsBody has an owning node unless you have free bodies not attached to nodes. If you want to be safe, just check for nil here.

Upvotes: 2

Related Questions