在保持接触的同时避免在 iOS 上的 spriteKit 中发生碰撞

Avoiding collision in spriteKit on iOS while maintaining contact

我有 2 个 physicsBodies 并且不希望它们发生碰撞(即它们必须相互穿过)但仍然希望在发生接触时得到通知,但是当将 collisionBitMask 设置为 0 时,接触事件不会发生叫了。我做错了什么?

let stoneCategory  : UInt32 = 0x1 << 1
let birdCategory  : UInt32 = 0x1 << 2

physicsWorld.contactDelegate = self

stoneNode = SKSpriteNode(imageNamed: "Stone");
self.addChild(stoneNode)
stoneNode.physicsBody = SKPhysicsBody(rectangleOf: stoneNode.size);
stoneNode.physicsBody?.categoryBitMask = stoneCategory
stoneNode.physicsBody?.contactTestBitMask = birdCategory
stoneNode.physicsBody?.collisionBitMask = 0

birdNode = SKSpriteNode();
<...Set texture...> 
self.addChild(birdNode)
birdNode.physicsBody = SKPhysicsBody(rectangleOf: birdNode.size);
birdNode.physicsBody?.categoryBitMask = birdCategory
birdNode.physicsBody?.contactTestBitMask = stoneCategory
birdNode.physicsBody?.collisionBitMask = 0
birdNode.physicsBody?.isDynamic = false;

func didBegin(_ contact: SKPhysicsContact) {
    print("Contact between "+contact.bodyA.node!.name!+" and "+contact.bodyB.node!.name!); // --> Never called
}

您的代码在其他地方可能有不同的问题,因为这对我有用。身体不会碰撞,会发生接触。

游乐场示例代码:

import PlaygroundSupport
import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {
    
    var stoneNode: SKShapeNode!
    var birdNode: SKShapeNode!
    
    override func didMove(to view: SKView) {
        
        let stoneCategory  : UInt32 = 0x1 << 1
        let birdCategory  : UInt32 = 0x1 << 2

        physicsWorld.contactDelegate = self

        stoneNode = SKShapeNode(circleOfRadius: 30)
        stoneNode.name = "stone"
        stoneNode.position = CGPoint(x: 0, y: 100)
        addChild(stoneNode)
        stoneNode.physicsBody = SKPhysicsBody(circleOfRadius: 30)
        stoneNode.physicsBody?.categoryBitMask = stoneCategory
        stoneNode.physicsBody?.contactTestBitMask = birdCategory
        stoneNode.physicsBody?.collisionBitMask = 0

        birdNode = SKShapeNode(circleOfRadius: 40)
        birdNode.name = "bird"
        birdNode.position = CGPoint(x: 0, y: -100)
        addChild(birdNode)
        birdNode.physicsBody = SKPhysicsBody(circleOfRadius: 40);
        birdNode.physicsBody?.categoryBitMask = birdCategory
        birdNode.physicsBody?.contactTestBitMask = stoneCategory
        birdNode.physicsBody?.collisionBitMask = 0
        birdNode.physicsBody?.isDynamic = false;
    }
    
    func didBegin(_ contact: SKPhysicsContact) {
        print("Contact between "+contact.bodyA.node!.name!+" and "+contact.bodyB.node!.name!); // --> Never called
    }
}

// Load the SKScene from 'GameScene.sks'
let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480))
if let scene = GameScene(fileNamed: "GameScene") {
    // Set the scale mode to scale to fit the window
    scene.scaleMode = .aspectFill
    
    // Present the scene
    sceneView.presentScene(scene)
}

PlaygroundSupport.PlaygroundPage.current.liveView = sceneView

并且在控制台中,当第一个 body 掉落时,受重力影响,它被打印:

Contact between stone and bird