由于您尚未正确设置分类、联系人和碰撞位掩码,因此无法获得所期望的行为。以下是一个示例,说明如何设置才能正常工作:
greenBall.physicsBody?.categoryBitMask = GreenBallCategory //Category is GreenBall
greenBall.physicsBody?.contactTestBitMask = RedBarCategory | WallCategory //Contact will be detected when GreenBall make a contact with RedBar or a Wall (assuming that redBar's masks are already properly set)
greenBall.physicsBody?.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory //Collision will occur when GreenBall hits GreenBall, RedBall or hits a Wall
redBall.physicsBody?.categoryBitMask = RedBallCategory //Category is RedBall
redBall.physicsBody?.contactTestBitMask = GreenBarCategory | GreenBallCategory | WallCategory //Contact will be detected when RedBall make a contact with GreenBar , GreenBall or a Wall
redBall.physicsBody?.collisionBitMask = RedBallCategory | GreenBallCategory | WallCategory //Collision will occur when RedBall meets RedBall, GreenBall or hits a Wall
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody = borderBody
self.physicsBody?.friction = 0
borderBody.contactTestBitMask = RedBallCategory | GreenBallCategory //Contact will be detected when red or green ball hit the wall
borderBody.categoryBitMask = WallCategory
borderBody.collisionBitMask = RedBallCategory | GreenBallCategory // Collisions between RedBall GreenBall and a Wall will be detected
我建议您阅读有关categoryBitMask的文档,这是一个定义物理体所属类别的掩码:
场景中的每个物理体最多可以分配到32个不同的类别,每个类别对应掩码中的一位。您可以在游戏中定义使用的掩码值。结合collisionBitMask和contactTestBitMask属性,您可以定义哪些物理体彼此交互以及何时通知游戏这些交互。
contactTestBitMask - 定义与当前物理体发生交集通知的物体类别掩码。
当两个物体占用相同空间时,将通过执行逻辑AND操作来测试每个物体的类别掩码是否与另一个物体的接触掩码相匹配。如果任何一个比较结果为非零值,则创建一个SKPhysicsContact对象并传递给物理世界的委托。为获得最佳性能,请仅设置联系掩码中感兴趣的交互位。
collisionBitmask - 定义可以与此物理体发生碰撞的物理体类别掩码。
当两个物理体彼此接触时,可能会发生碰撞。通过执行逻辑AND操作来比较该物体的碰撞掩码与其他物体的类别掩码。如果结果为非零值,则该物体会受到碰撞的影响。每个物体都独立选择是否希望受到其他物体的影响。例如,您可以使用它来避免对速度变化微不足道的物体进行碰撞计算。
因此,基本上要设置所有这些内容,您应该问自己类似以下问题:
好的,我在场景中有一个绿球、一个红球和一些墙壁对象。我希望哪些物体之间发生碰撞,或者何时注册联系?我想让绿色和红色的球互相碰撞,并与墙壁发生碰撞。没有问题。我将首先适当地设置类别,然后将设置碰撞位掩码如下:
greenBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory; //greenBall will collide with greenBall, redBall and a wall
redBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory
wall.collisionBitMask = GreenBall | RedBall
现在,我想检测某些接触事件(在didBeginContact
方法中)... 但我不想收到所有可能的接触事件通知,而是只想收到有关球之间的接触事件通知(球与墙之间的接触事件将被忽略)。 因此,让我们设置contactTestBitMasks
以实现此目的:
greenBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
redBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
就是这样。重要的是,当你不使用接触检测时,不应该设置contactTestBitMask
,因为这会影响性能。如果你不需要碰撞检测,并且只对检测接触感兴趣,可以将collisionBitMask = 0
。
重要提示:
确保已经设置了物理世界的接触代理以便使用didBeginContact
和didEndContact
方法:
self.physicsWorld.contactDelegate = self; //where self is a current scene
希望这有点帮助。