SpriteKit / Swift - How to check contact of two no

2020-07-24 05:34发布

问题:

In my game, when the game begins, some nodes are already in contact but I don't find how to detect these contacts. I only succeed to detect contacts that happen when nodes are moving and getting in contact during the game using the function didBeginContact.

Anyone has an idea please how to detect these contacts?

Here is my didBeginContact if needed:

func didBeginContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody
    if contact.bodyA.categoryBitMask == contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB

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

回答1:

I've just tried to make two sprites overlap from the very beginning and contact is detected for me. Here is the code:

import SpriteKit

struct Collider {
    static let SmallSquare     : UInt32 = 1 << 0
    static let BigSquare       : UInt32 = 1 << 1
}

class GameScene: SKScene, SKPhysicsContactDelegate {

    override func didMoveToView(view: SKView) {

        self.physicsWorld.contactDelegate = self

        let smallSquare = SKSpriteNode(color: .orangeColor(), size: CGSize(width: 50, height:50))
        smallSquare.zPosition = 2
        smallSquare.position = CGPoint(x: frame.midX, y: frame.midY)
        smallSquare.physicsBody = SKPhysicsBody(rectangleOfSize: smallSquare.size)
        smallSquare.physicsBody?.affectedByGravity = false
        smallSquare.physicsBody?.categoryBitMask = Collider.SmallSquare
        smallSquare.physicsBody?.contactTestBitMask = Collider.BigSquare
        smallSquare.physicsBody?.collisionBitMask = 0
        addChild(smallSquare)

        let bigSquare = SKSpriteNode(color: .purpleColor(), size: CGSize(width: 200, height: 200))
        bigSquare.zPosition = 1
        bigSquare.position = CGPoint(x: frame.midX, y: frame.midY)
        bigSquare.physicsBody = SKPhysicsBody(rectangleOfSize: bigSquare.size)
        bigSquare.physicsBody?.affectedByGravity = false
        bigSquare.physicsBody?.categoryBitMask = Collider.BigSquare
        bigSquare.physicsBody?.contactTestBitMask = Collider.SmallSquare
        bigSquare.physicsBody?.collisionBitMask = 0
        addChild(bigSquare)

    }

    func didBeginContact(contact: SKPhysicsContact) {

        print("Contact detected")
    }    
}

Later on, to appropriately detect contact between certain bodies, you should do something like this:

func didBeginContact(contact: SKPhysicsContact) {

        var firstBody, secondBody: SKPhysicsBody

        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {

            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {

            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }


        if ((firstBody.categoryBitMask & Collider.SmallSquare) != 0 &&
            (secondBody.categoryBitMask & Collider.BigSquare != 0)) {

                print ("Contact detected")
        }

    }

But even without that, the message will be printed when game is started for the first time because contact is detected by physics world anyways.