防止两个相同类型的SKPhysicBody之间重叠

时间:2018-11-13 15:20:59

标签: swift sprite-kit skphysicsbody

我有一个游戏,其中两个球应该能够通过第三个物体,该物体充当终点线。这两个球是SKShapeNodes,终点“线”是SKSpriteNode。它们都带有SKPhysicBodys,它们的类别设置如下:

struct PhysicsCategory {
    static let ball: UInt32 = 0x1 << 1
    static let line: UInt32 = 0x1 << 2
}


ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = 1

line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 1

由于我希望球能够越过终点线而不会发生碰撞,同时仍然能够得到有关此的通知,因此我将球和线的collisionBitMask设置为相同的值。

这给了我想要的结果。但是,这似乎有一个副作用,即两个球也能够彼此通过,这是不应该发生的。

此外,如果我将collisionBitMask的值设置为1以外的值,则球和线会相互碰撞。我已经阅读了苹果的文档,但是我想我在这里误解了/错过了一些东西。

我的猜测是,由于两个球相互看具有相同的collisionBitMask。发生重叠是可以预期的。我不知道如何避免这种情况,而不必在每个球上添加单独的类别。

有人能指出我正确的方向吗?如何在不互相重叠的情况下使球穿过终点线?

1 个答案:

答案 0 :(得分:0)

我倾向于不时将其混淆,但希望我能正确地记住这一点。

如果您仅关心的是将冲突呼叫重新接到主要受contactTestBitMask控制的线路上,则可以按原样打球。这就是将联系人发送到委托方法的原因。 collisionBitMask控制实际控制物理计算的内容,即将互相影响的内容。

默认情况下,collisionBitMask将与所有内容发生碰撞,因此您只想指定要用于计算物理的对象。您已将所有内容都设置为1,这不是场景中特定的内容。这就是为什么所有事物都相互穿越的原因。我相信2将是ball,而4将与您提供的一致(如果您打印出PhysicsCategory.ball和PhysicsCategory.line就是它注销的内容)。通常,最佳做法是使用您创建的枚举或结构而不是指定数字。话虽如此,我还是一无所获。

要解决此问题,您想告诉您的球您希望它们与PhysicsCategory.ball发生碰撞,并且希望您的线与任何物体都不发生碰撞,因此您希望将其设置为0。

struct PhysicsCategory {
    static let ball: UInt32 = 0x1 << 1
    static let line: UInt32 = 0x1 << 2
}


ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = PhysicsCategory.ball //changed to ball

line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 0 //you want no physics calculations