是否有可能停用spriteKit物理机构中的碰撞?

我正在寻找在我的spriteKit游戏中为我的英雄收集物品的最佳方式,在尝试了几种方法来做到这一点之后,我的结论是最好的方法是将物品与物理物体可以检测到碰撞,但不会与我的英雄相撞。 可以做到吗? 停用物理碰撞而不失去检测碰撞的能力? 听起来有点矛盾,我知道…因为,另一种方法是只创build一个没有物理体的SKSpriteNode,那么就不会有碰撞,但是“检测”碰撞的方法是手工制造的,而且更加困难,因为我需要在我的英雄中设置一个坐标系检测,当他将在这些具体的坐标(在物品上)时,我会使物品消失。 任何想法如何做到这两种方式中的任何一种更容易?

查看SKPhysicsBody类中的collisionBitMask , categoryBitMask和contactTestBitMask 。

本质上,具有相同collisionBitMask值的物理实体将相互“传递”。

  • 更正:如果类别和冲突位匹配 ,它们将相互作用。 如果他们不匹配 ,这两个不会互动。 如果碰撞位和类别位都是 ,那么这个项目当然不会互相影响

然后,您设置categoryBitMaskcontactTestBitMask值以在联系人上创buildSKPhysicsContact对象。 最后,你的类应该采用SKPhysicsContactDelegate协议。 使用- didBeginContact:方法来检测和处理SKPhysicsContact对象。

 static const uint8_t heroCategory = 1; static const uint8_t foodCategory = 2; -- food.physicsBody.categoryBitMask = foodCategory; food.physicsBody.contactTestBitMask = heroCategory; food.physicsBody.collisionBitMask = 0; -- hero.physicsBody.categoryBitMask = heroCategory; hero.physicsBody.contactTestBitMask = foodCategory; hero.physicsBody.collisionBitMask = 0; -- -(void)didBeginContact:(SKPhysicsContact *)contact { SKPhysicsBody *firstBody = contact.bodyA; SKPhysicsBody *secondBody = contact.bodyB; } 

简短的回答:

 yourHero.physicsBody.collisionBitMask = 0; 

collisionBitMask的默认值是0xFFFFFFFF(所有位设置),这就是为什么节点与其他

你可以通过设置player的categoryBitMask和contactBitMasks和item对象来做到这一点,但是要确保你不要设置collisionBitMask来互相交互(见下面)

 static const int playerCategory = 1; static const int worldCategory = 2; static const int objectCategory = 4; .... SKSpriteNode *player, *item; .... player.physicsBody.categoryBitMask = playerCategory; player.physicsBody.collisionBitMask = worldCategory; player.physicsBody.contactTestBitMask = worldCategory; .... item.physicsBody.categoryBitMask = objectCategory; item.physicsBody.contactTestBitMask = playerCategory | worldCategory; item.physicsBody.collisionBitMask = worldCategory; 

通过这种方式,物理机构将拾取玩家与世界物体,物品和世界物体之间的碰撞,但不会在玩家与物品之间发生碰撞。 它会触发didBeginContact的调用,在那里你可以删除你的项目节点,添加健康等。

希望这可以帮助!

contactTestBitMask用于触发didBeginContactcollisionBitMask用于激活节点上的物理。

 // add a physics body ship.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ship.size.width/2]; // set the category for ship ship.physicsBody.categoryBitMask = shipCategory; // detect collisions with asteroids and edges ship.physicsBody.contactTestBitMask = asteroidCategory | edgeCategory; // physically collide with asteroids ship.physicsBody.collisionBitMask = asteroidCategory;