iOS如何检查三个精灵是否有联系

时间:2023-01-17 14:16:36

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)

我知道如何在spritekit(使用contact)中检查两个精灵是否有接触。body和contact.bodyB)。谁能解释一下我如何检查三个精灵之间是否有联系?(三个方形的精灵互相接触,因为它们是叠在一起的)

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?

编辑:我发现可以使用所有的接触体,找到所有的接触体。请参见下面的代码。但由于某些原因,for循环会出现错误。错误:“[AnyObject]?“没有一个叫‘生成器’的成员,有人怎么解决这个问题?”

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()
                }
            }
        }
    }
}

3 个解决方案

#1


1  

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).

首先,如果主体处于接触状态,它们的位掩码至少会重叠,因此不需要检查位掩码(除非您希望尽可能详细)。同样,如果你假设。bodya。节点不是nil,那么你可以假设它有一个物理体,因为它正在被接触(这只有在物理体中才可能)。

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...".

同样,你感兴趣的三个(或更多)的身体接触,所以你只需要检查多个身体接触一个身体,所以检查> 1意味着“如果有两个以上的身体(如三)参与这种接触然后……”。

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.

最后,物体包含一系列SKPhysicsBody对象,它们没有nil值(如果它们是nil,那么它们就不会参与碰撞),所以将物体中的任何物体投射到SKPhysicsBody上是安全的。你可以假设物理体有一个拥有的节点,除非你有不依附于节点的*体。如果你想要安全,在这里检查nil。

#2


0  

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()
            }
        }
    }
}

#3


0  

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()
            }
        }
    }
}

#1


1  

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).

首先,如果主体处于接触状态,它们的位掩码至少会重叠,因此不需要检查位掩码(除非您希望尽可能详细)。同样,如果你假设。bodya。节点不是nil,那么你可以假设它有一个物理体,因为它正在被接触(这只有在物理体中才可能)。

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...".

同样,你感兴趣的三个(或更多)的身体接触,所以你只需要检查多个身体接触一个身体,所以检查> 1意味着“如果有两个以上的身体(如三)参与这种接触然后……”。

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.

最后,物体包含一系列SKPhysicsBody对象,它们没有nil值(如果它们是nil,那么它们就不会参与碰撞),所以将物体中的任何物体投射到SKPhysicsBody上是安全的。你可以假设物理体有一个拥有的节点,除非你有不依附于节点的*体。如果你想要安全,在这里检查nil。

#2


0  

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()
            }
        }
    }
}

#3


0  

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()
            }
        }
    }
}