Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c SKPhysicsContact有没有办法确定哪个物体是A和B?_Objective C_Swift_Sprite Kit_Game Physics - Fatal编程技术网

Objective c SKPhysicsContact有没有办法确定哪个物体是A和B?

Objective c SKPhysicsContact有没有办法确定哪个物体是A和B?,objective-c,swift,sprite-kit,game-physics,Objective C,Swift,Sprite Kit,Game Physics,在SpriteKit中,我们通过didBeginContact方法检测到了。 但这样做看起来有点愚蠢: func didBeginContact(联系人:SKPhysicsContact){ 是否有任何方法可以确保bodyA始终是一个球?是否有任何与categorybitmask相关的规则?如果使用简单的类别,每个物理体只属于一个类别,那么didBeginContact的这种替代形式可能更具可读性: func didBeginContact(contact: SKPhysicsContact)

在SpriteKit中,我们通过didBeginContact方法检测到了。 但这样做看起来有点愚蠢: func didBeginContact(联系人:SKPhysicsContact){


是否有任何方法可以确保bodyA始终是一个球?是否有任何与categorybitmask相关的规则?

如果使用简单的类别,每个物理体只属于一个类别,那么didBeginContact的这种替代形式可能更具可读性:

func didBeginContact(contact: SKPhysicsContact) {
    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

switch contactMask {

   case categoryBitMask.ball | categoryBitMask.something:
       print("Collision between ball and something")
       let ballNode = contact.bodyA.categoryBitMask == categoryBitMask.ball ? contact.bodyA.node! : contact.bodyB.node!
       ballNode.pop()
       score += 10

   default :
       //Some other contact has occurred
       print("Some other contact")
   }
}

请注意,如果您的类别更复杂,这将无法像简单测试那样工作,并且测试(
categoryBitMask.ball | categoryBitMask.something
)将不匹配。

通常您会这样做

首先,如果您还没有存储位掩码类别,则需要存储位掩码类别

enum PhysicsCategory {
     static let ball: UInt32 =  0x1 << 0
     static let wall: UInt32 =  0x1 << 1
     static let enemy: UInt32 = 0x1 << 2
}
注意:因为在本例中,球会同时检查与墙和敌人的接触,所以您不需要告诉墙或敌人检查与球的接触。 在1物理体上执行此操作很好,因此您可以在其他物理体上将其设置为0,除非他们有其他特定联系人要查找

然后,您可以像这样在contact方法中检查它们,而无需使用double if语句

func didBegin(_ contact: SKPhysicsContact) {

    let firstBody: SKPhysicsBody
    let secondBody: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }


    // Ball hit wall or wall hit ball
    if (firstBody.categoryBitMask == PhysicsCategory.ball) && (secondBody.categoryBitMask == PhysicsCategory.wall) {

          // Some code
    }

    // Ball hit enemy or enemy hit ball
    if (firstBody.categoryBitMask == PhysicsCategory.ball) && (secondBody.categoryBitMask == PhysicsCategory.enemy) {

          // Some code
    }
}

希望这有助于

在多个联系人同时出现的情况下,此代码在某些情况下可能会崩溃。假设您有三个对象相交。SpriteKit一次只能处理一个联系人。并假设您正在删除对象(类型)当父对象A与类型B或C的对象接触时,它将从父对象A中删除。因此将调用两次didBeginContact。如果从其父对象A中删除对象A,则在下一次didBeginContact调用中,强制展开将失败。您应该指示他不要像这样使用强制展开,因为节点属性可能为零……否则,它应该可以工作,并且它是无效的可读:)@Whirlwind这是否意味着
如果let
guard
在这里有用?@困惑最像是let或guard是的。甚至是可选的链接。只是为了防止潜在的崩溃。这可能会发生……我(最近)开始了解如何以及为什么要使用
if let
,还没有时间去弄清楚
如何保护
。但是我喜欢玩物理引擎,所以这看起来是一个很好的借口,可以找到如何在合理的位置有目的地使用它。谢谢!!!我深入研究了SKTemplate对
if let
的使用
copy()
SKShapeNodes
。当我意识到它真的在做两件事时,这是一个富有洞察力的时刻。1.将一个可选项转换为一个同名的实际项,2.提供一个在一个范围内做一系列事情的机会。我仍然在外面吃午饭,讨论关闭该范围内的某些内容的好处,正如S的回答中所发生的那样teve,其中我为ballNode赋值放置了一个
if-let
,它将包装pop()调用并添加到score变量。在这种情况下,这是使用
if-let
的正确位置/想法吗?
 ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
 ball.physicsBody?.contactTestBitMask = PhysicsCategory.wall | PhysicsCategory.enemy

 wall.physicsBody?.categoryBitMask = PhysicsCategory.wall
 wall.physicsBody?.contactTestBitMask = 0 

 enemy.physicsBody?.categoryBitMask = PhysicsCategory.enemy
 enemy.physicsBody?.contactTestBitMask = 0 
func didBegin(_ contact: SKPhysicsContact) {

    let firstBody: SKPhysicsBody
    let secondBody: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }


    // Ball hit wall or wall hit ball
    if (firstBody.categoryBitMask == PhysicsCategory.ball) && (secondBody.categoryBitMask == PhysicsCategory.wall) {

          // Some code
    }

    // Ball hit enemy or enemy hit ball
    if (firstBody.categoryBitMask == PhysicsCategory.ball) && (secondBody.categoryBitMask == PhysicsCategory.enemy) {

          // Some code
    }
}
physicsWorld.contactDelegate = self