Sprite-Kit:带有两个精灵的彩色xor逻辑。黑色+黑色=白色

时间:2017-09-23 21:51:53

标签: ios colors sprite-kit xor

你知道益智游戏“voi”吗?这是一款与color-XOR逻辑兼容的游戏。这意味着:黑色+黑色=白色。

https://www.youtube.com/watch?v=Aw5BdVcAtII

有没有办法在sprit工具包中使用两个sprite节点进行相同的颜色逻辑?

感谢。

1 个答案:

答案 0 :(得分:0)

当然,可以在Sprite Kit中执行此操作。

<强>问题:

假设您有2个黑色方块,squareAsquareB。用户可以在任何他想要的地方拖动这两个方块。他一次只能拖动一个方格。每当两个正方形相交时,您希望将相交区域着色为白色。

初始设置:

在场景的顶部,我们需要创建一些变量:

private var squareA: SKSpriteNode?
private var squareB: SKSpriteNode?
private var squares = [SKSpriteNode]()
private var selectedShape: SKSpriteNode?
private var intersectionSquare: SKShapeNode?
  • squareAsquareB只是我们最初在屏幕上显示的2个方格。
  • squares是一个数组,它将存储屏幕上显示的所有正方形。
  • selectedShape将帮助我们跟踪当前被拖动的方块。
  • intersectionSquare是一个白色方块,代表两个黑色方块之间的交叉区域。

然后初始化squareAsquareB,并将它们添加到squares数组中,如下所示:

    squareA = SKSpriteNode(color: .black, size: CGSize(width: 190.0, height: 190.0))

    if let squareA = self.squareA {
        squareA.position = CGPoint(x: -200, y: 200)
        squareA.name = "Square A"
        squares.append(squareA)
        self.addChild(squareA)
    }

    // Do the same for squareB or any other squares that you have on screen..

注意:正如您所看到的,我在这里给它起了一个名字,以便在测试阶段更容易区分它们。

检测用户何时拖动方块:

现在,您需要检测用户何时拖动方块。为此,您可以使用:

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { self.touchDown(atPoint: t.location(in: self)) }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { self.touchUp(atPoint: t.location(in: self)) }
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { self.touchUp(atPoint: t.location(in: self)) }
    }

这些只是辅助方法,可以让我们的生活更轻松。

然后,您需要设置touchDowntouchMovedtouchUp方法:

 func touchDown(atPoint pos : CGPoint) {

        let touchedNode = self.nodes(at: pos)

        guard let selectedSquare = touchedNode.first as? SKSpriteNode else {
            return
        }

        selectedShape = selectedSquare
    }

    func touchMoved(toPoint pos : CGPoint) {

        guard let selectedSquare = self.selectedShape else {
            return
        }

        selectedSquare.position = pos

        checkIntersectionsWith(selectedSquare)
    }

    func touchUp(atPoint pos : CGPoint) {
        selectedShape = nil
    }

更详细地向您解释这里发生了什么:

  • touchDown方法中:

好吧,我们需要用户一次只能拖动一个方格。使用nodes(at:)方法,很容易知道触摸了哪个方格,并且我们可以知道将selectedShape变量设置为等于被触摸的方格。

  • touchMoved方法中:

这里我们基本上只是将selectedShape移动到用户移动手指的位置。我们还会调用我们将在一秒钟内设置的checkIntersectionsWith()方法。

  • touchUp方法中:

用户将手指从屏幕上松开,因此我们可以将selectedShape设置为零。

更改交叉点框架的颜色:

现在,让你的游戏看起来像你想要制作的最重要的部分是,当两个黑色方块相交时,如何将交叉帧的颜色更改为白色?

嗯,这里有不同的可能性,这是一种可行的方法:

private func checkIntersectionsWith(_ selectedSquare: SKSpriteNode) {

    for square in squares {

        if selectedSquare != square && square.intersects(selectedSquare) {

            let intersectionFrame = square.frame.intersection(selectedSquare.frame)

            intersectionSquare?.removeFromParent()
            intersectionSquare = nil

            intersectionSquare = SKShapeNode(rect: intersectionFrame)

            guard let interSquare = self.intersectionSquare else {
                return
            }

            interSquare.fillColor = .white
            interSquare.strokeColor = .clear
            self.addChild(interSquare)

        }  else if selectedSquare != square {

            intersectionSquare?.removeFromParent()
            intersectionSquare = nil
        }
    }
}

每次调用checkIntersectionsWith()方法时,我们都会迭代squares数组中的节点,并使用框架的intersection()方法检查所选方块与这些中的任何一个相交(除了它自己)。如果是,那么我们创建一个名为intersectionSquare的白色方块,并将其框架设置为等于交叉框架。

为了节省内存使用量,您可以从场景中删除方块,如果根本没有交叉点,则将intersectionSquare设置为nil

最终结果:

最终结果如下:

enter image description here

这只是一个快速的草稿,我向你展示你可以解决问题,显然有很多事情你可以添加或改进(应用于你不仅有2个但在屏幕上有很多方块的情况当用户从屏幕上松开手指等时,或创造一种磁效应,但我希望至少它会让你的项目走上正轨:)