Ios 检查两个节点相互接触时是否具有相同的颜色

Ios 检查两个节点相互接触时是否具有相同的颜色,ios,swift,sprite-kit,swift3,skspritenode,Ios,Swift,Sprite Kit,Swift3,Skspritenode,我是斯威夫特的新手,所以如果我犯了新手错误,我向你道歉。我试图让两个盒子在接触时消失,如果两个盒子颜色相同。到目前为止,我有以下代码: 此代码设置游戏: import SpriteKit import GameplayKit class GameScene: SKScene, SKPhysicsContactDelegate { override func didMove(to view: SKView) { physicsBod

我是斯威夫特的新手,所以如果我犯了新手错误,我向你道歉。我试图让两个盒子在接触时消失,如果两个盒子颜色相同。到目前为止,我有以下代码:

此代码设置游戏:

    import SpriteKit
    import GameplayKit

    class GameScene: SKScene, SKPhysicsContactDelegate {
        override func didMove(to view: SKView) {
            physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
            physicsWorld.contactDelegate = self

            let background = SKSpriteNode(imageNamed: "background.jpg")
            background.size = self.frame.size;
            background.position = CGPoint(x: 0, y: 0)
            background.blendMode = .replace
            background.zPosition = -1
            addChild(background)

        }
生成随机颜色的代码:

        enum Color {
            case ColorRed
            case ColorGreen
            case ColorBlue

            public var color: UIColor {
                switch self {
                case .ColorRed: return UIColor(red: 255, green: 0, blue: 0, alpha: 1)
                case .ColorGreen: return UIColor(red: 0, green: 255, blue: 0, alpha: 1)
                case .ColorBlue: return UIColor(red: 0, green: 0, blue: 255, alpha: 1)
                }
            }

            static var all: [Color] = [.ColorRed, .ColorGreen, .ColorBlue]

            static var randomColor: UIColor {
                let randomIndex = Int(arc4random_uniform(UInt32(all.count)))
                return all[randomIndex].color
            }
        }
这是重要的部分-对象之间的实际接触:

    func didBegin(_ contact: SKPhysicsContact) {

        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {

            let firstBody = contact.bodyA.node as! SKSpriteNode!
            let secondBody = contact.bodyB.node as! SKSpriteNode!

            if firstBody!.color == secondBody!.color {
                firstBody!.removeFromParent()
                secondBody!.removeFromParent()
            }
        } else {

            let firstBody = contact.bodyB.node as! SKSpriteNode!
            let secondBody = contact.bodyA.node as! SKSpriteNode!

            if firstBody!.color == secondBody!.color {
                firstBody!.removeFromParent()
                secondBody!.removeFromParent()
            }
        }
    }
func didbeagin(uu联系人:skphysiccontact){
如果contact.bodyA.categoryBitMask
最后是用户触摸屏幕时的代码:

        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            if let touch = touches.first {
                let location = touch.location(in: self)
                let box = SKSpriteNode(color: UIColor.red, size: CGSize(width: 64, height: 64))
                box.color = Color.randomColor
                box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 64, height: 64))
                box.position = location
                addChild(box)
            }
        }
override func touchsbegind(touch:Set,带有事件:UIEvent?){
如果让触摸=先触摸{
让位置=触摸。位置(in:self)
let box=SKSpriteNode(颜色:UIColor.red,大小:CGSize(宽:64,高:64))
box.color=color.randomColor
box.physicsBody=SKPhysicsBody(矩形:CGSize(宽:64,高:64))
box.position=位置
addChild(框)
}
}

我已经提供了所有的代码,所以你知道设置。提前感谢您的帮助。

首先,为
类别BitMask
声明一个
结构:

struct ColorMask {
    static let Red: UInt32 = 0x1 << 0
    static let Green: UInt32 = 0x1 << 1
    static let Blue: UInt32 = 0x1 << 2
}
我只是将上面的代码改为返回
Color
,而不是
UIColor

第三,将
didbeagin
修改为:

func didBegin(_ contact: SKPhysicsContact) {
    if contact.bodyA.categoryBitMask == contact.bodyB.categoryBitMask {
        let firstBody = contact.bodyA.node as! SKSpriteNode!
        let secondBody = contact.bodyB.node as! SKSpriteNode!

        firstBody!.removeFromParent()
        secondBody!.removeFromParent()
    }
}
在上面的代码中,只需比较
categoryBitMask
就足够了,因为我稍后将使用相同的
categoryBitMask
设置具有相同颜色的主体

最后,使用以下代码将
categoryBitMask
设置到框中:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let location = touch.location(in: self)
        let box = SKSpriteNode(color: UIColor.red, size: CGSize(width: 64, height: 64))
        let color = Color.randomColor
        box.color = color.color
        box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 64, height: 64))
        if color == Color.ColorRed {
            box.physicsBody?.categoryBitMask = ColorMask.Red
        } else if color == Color.ColorGreen {
            box.physicsBody?.categoryBitMask = ColorMask.Green
        }else if color == Color.ColorBlue {
            box.physicsBody?.categoryBitMask = ColorMask.Blue
        }
        box.physicsBody?.contactTestBitMask = ColorMask.Red | ColorMask.Green | ColorMask.Blue
        box.position = location
        addChild(box)
    }
}
override func touchsbegind(touch:Set,带有事件:UIEvent?){
如果让触摸=先触摸{
让位置=触摸。位置(in:self)
let box=SKSpriteNode(颜色:UIColor.red,大小:CGSize(宽:64,高:64))
让color=color.randomColor
box.color=color.color
box.physicsBody=SKPhysicsBody(矩形:CGSize(宽:64,高:64))
如果颜色==color.ColorRed{
box.physicsBody?.categoryBitMask=彩色Mask.Red
}如果color==color.ColorGreen,则为else{
box.physicsBody?.categoryBitMask=彩色Mask.Green
}如果color==color.ColorBlue,则为else{
box.physicsBody?.categoryBitMask=ColorMask.Blue
}
box.physicsBody?.contactTestBitMask=ColorMask.Red | ColorMask.Green | ColorMask.Blue
box.position=位置
addChild(框)
}
}

您未正确设置contactBitMask,因此未检测到任何联系人。。。默认情况下,由于性能原因,此掩码的默认值为零:

当两个实体共享同一空间时,每个实体的类别遮罩为 通过执行逻辑测试,针对另一个身体的接触面具进行测试 和操作。如果其中一个比较结果为非零值,则 SKPhysicContact对象被创建并传递给物理世界的 代表。为获得最佳性能,仅在联系人掩码中设置 你感兴趣的互动

默认值为0x00000000(所有位均已清除)

要解决此问题,请将contact和category位掩码都设置为适当的值,如下所示:

class GameScene: SKScene,SKPhysicsContactDelegate {

    override func didMove(to view: SKView) {
        self.physicsWorld.contactDelegate = self

        physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
        physicsWorld.contactDelegate = self


    }

    func didBegin(_ contact: SKPhysicsContact) {

        if let bodyA = contact.bodyA.node as? SKSpriteNode,
           let bodyB = contact.bodyB.node as? SKSpriteNode{
            //Of course this is simple example and you will have to do some "filtering" to determine what type of objects are collided.
           // But the point is , when appropriate objects have collided, you compare their color properties.
            if bodyA.color == bodyB.color {
                bodyA.run(SKAction.removeFromParent())
                bodyB.run(SKAction.removeFromParent())
            }
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let location = touch.location(in: self)
            let box = SKSpriteNode(color: UIColor.red, size: CGSize(width: 64, height: 64))
            box.color = Color.randomColor

            box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 64, height: 64))
            box.physicsBody?.contactTestBitMask = 0b1
            box.physicsBody?.categoryBitMask = 0b1
            box.position = location
            addChild(box)
        }
    }
}
类游戏场景:SKScene,skphysiccontactdelegate{
覆盖func didMove(到视图:SKView){
self.physicsWorld.contactDelegate=self
physicsBody=SKPhysicsBody(edgeLoopFrom:frame)
physicsWorld.contactDelegate=self
}
func didbegen(uu联系人:skphysiccontact){
如果让bodyA=联系.bodyA.node作为?SKSpriteNode,
设bodyB=contact.bodyB.node为?SKSpriteNode{
//当然,这是一个简单的示例,您必须进行一些“过滤”以确定碰撞的对象类型。
//但关键是,当适当的对象发生碰撞时,可以比较它们的颜色属性。
如果bodyA.color==bodyB.color{
bodyA.run(SKAction.removeFromParent())
bodyB.run(SKAction.removeFromParent())
}
}
}
覆盖func TouchesBegind(Touchs:Set,带有事件:UIEvent?){
如果让触摸=先触摸{
让位置=触摸。位置(in:self)
let box=SKSpriteNode(颜色:UIColor.red,大小:CGSize(宽:64,高:64))
box.color=color.randomColor
box.physicsBody=SKPhysicsBody(矩形:CGSize(宽:64,高:64))
box.physicsBody?.contactTestBitMask=0b1
box.physicsBody?.categoryBitMask=0b1
box.position=位置
addChild(框)
}
}
}

现在,当两个实体之间发生接触时,如文档中所述,通过执行逻辑“与”运算,每个实体的类别位掩码将与另一个实体的接触掩码一起测试。如果结果为非零,则会出现联系人通知。在本例中,这将是1&1=1。

当您运行代码时,实际看到的是什么,以及它与您期望的有什么不同。还有一半的func didbeagin是多余的,因为无论节点以何种方式进入函数,都会删除它们。它与您要求的内容无关,但为什么要为颜色创建枚举?为什么不创建静态计算属性“随机”
class GameScene: SKScene,SKPhysicsContactDelegate {

    override func didMove(to view: SKView) {
        self.physicsWorld.contactDelegate = self

        physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
        physicsWorld.contactDelegate = self


    }

    func didBegin(_ contact: SKPhysicsContact) {

        if let bodyA = contact.bodyA.node as? SKSpriteNode,
           let bodyB = contact.bodyB.node as? SKSpriteNode{
            //Of course this is simple example and you will have to do some "filtering" to determine what type of objects are collided.
           // But the point is , when appropriate objects have collided, you compare their color properties.
            if bodyA.color == bodyB.color {
                bodyA.run(SKAction.removeFromParent())
                bodyB.run(SKAction.removeFromParent())
            }
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let location = touch.location(in: self)
            let box = SKSpriteNode(color: UIColor.red, size: CGSize(width: 64, height: 64))
            box.color = Color.randomColor

            box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 64, height: 64))
            box.physicsBody?.contactTestBitMask = 0b1
            box.physicsBody?.categoryBitMask = 0b1
            box.position = location
            addChild(box)
        }
    }
}