如何在一种节点之间没有冲突

时间:2016-02-03 15:56:03

标签: ios swift sprite-kit

我正在尝试用一个玩家块和一些障碍块制作游戏。玩家可以与障碍物碰撞,但障碍物不应相互碰撞,而是相互“穿过”。我的位掩码有以下枚举:

enum bitMask: UInt32 {
    case player = 1
    case obstacle = 2
    case frame = 4
}

这是我定义播放器块的方式:

let player = SKSpriteNode(imageNamed: "yellow-square")
player.physicsBody = SKPhysicsBody(texture: player.texture!, size: player.frame.size)
player.physicsBody!.dynamic = false
player.physicsBody!.categoryBitMask = bitMask.player.rawValue
player.physicsBody!.contactTestBitMask = bitMask.obstacle.rawValue
player.physicsBody!.collisionBitMask = 0
addChild(player)
player.physicsBody!.contactTestBitMask = bitMask.obstacle.rawValue
player.physicsBody!.collisionBitMask = bitMask.frame.rawValue

我的障碍物块(在for循环中):

let obstacle = SKSpriteNode(imageNamed: "black-square")
obstacle.physicsBody = SKPhysicsBody(texture: obstacle.texture!, size: obstacle.frame.size)
boundaryNode.addChild(obstacle)
obstacle.physicsBody!.applyImpulse(CGVectorMake(-15, -10))
obstacle.physicsBody!.categoryBitMask = bitMask.obstacle.rawValue
obstacle.physicsBody!.contactTestBitMask = bitMask.player.rawValue

和我的联系功能:

func didBeginContact(contact: SKPhysicsContact) {
    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
    switch(contactMask) {
        case bitMask.player.rawValue | bitMask.obstacle.rawValue:
            let yourTimeNode = contact.bodyB.node
            yourTimeNode?.physicsBody?.allowsRotation = false

            let firstNode = contact.bodyA.node
            firstNode?.physicsBody?.allowsRotation = false

            print("Collision")
        default:
            return
    }
}

目前每个街区都相互碰撞,我不知道如何关闭障碍物之间的碰撞,并保持障碍物与玩家阻挡之间的碰撞。

1 个答案:

答案 0 :(得分:2)

您的代码中有一些内容需要更改。首先,您应该像这样制作位掩码

struct BitMask {
     static let player: UInt32 = 0x1 << 0
     static let obstacle: UInt32 = 0x1 << 1
     static let frame: UInt32 = 0x1 << 2
}

这样你只需要将最后一个数字增加1,如果你开始添加更多位掩码,这会让你的生活更轻松。比你这么称呼它

...categoryBitMask = BitMask.obstacle // no need for rawValue

比你应该改变你的联系方式看起来更像这个

/// Did Begin Contact
func didBeginContact(contact: SKPhysicsContact) {
    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

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

    if (firstBody.categoryBitMask == BitMask.player) && (secondBody.categoryBitMask == BitMask.obstacle) {
        // do your thing 
    }
}

最后在你的播放器和障碍代码中,首先在播放器代码中你重复2个值(contactBitMask / categoryBitMask),所以删除它们。 其次,你的障碍相互碰撞的原因是你没有为你的障碍设置collisionBitMask。这使它默认为0xFFFFFFFF,这意味着所有位都已设置,并且它将与所有内容进行交互。要修复它,请将其添加到障碍代码

 obstacle.physicsBody!.collisionBitMask = BitMask.player

现在让障碍物只与玩家发生碰撞。