Sprite-Kit:带有两个子画面的颜色异或逻辑。黑+黑=白
你知道益智游戏“voi”吗?这是一款适用于color-XOR逻辑的游戏。这意味着:黑+黑=白。Sprite-Kit:带有两个子画面的颜色异或逻辑。黑+黑=白
https://www.youtube.com/watch?v=Aw5BdVcAtII
有没有办法做同样的颜色逻辑与精神试剂盒检验两种精灵节点?
谢谢。
当然,在Sprite Kit中可以这样做。
问题:
比方说,你有2个黑色方块,squareA
和squareB
。用户可以将这两个方块拖到任何他想要的地方。他一次只能拖一个方格。只要两个正方形相交,就要将相交区域上色为白色。
初始设置:
在场景的顶部,有我们需要创建一些变量:
private var squareA: SKSpriteNode?
private var squareB: SKSpriteNode?
private var squares = [SKSpriteNode]()
private var selectedShape: SKSpriteNode?
private var intersectionSquare: SKShapeNode?
-
squareA
和squareB
仅仅是2个格,我们最初在屏幕上。 -
squares
是一个数组,它将存储屏幕上显示的所有正方形。 -
selectedShape
将帮助我们跟踪当前正在拖动的方块。 -
intersectionSquare
是一个白色正方形,表示两个黑色方块之间的交叉区域。
然后初始化squareA
和squareB
,并将它们添加到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)) }
}
这些只是帮助我们的生活更轻松的方法。
然后,你需要设置touchDown
,touchMoved
和touchUp
方法:
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
,如果根本没有交集。
最终结果:
最后的结果是这样的:
这只是一个快速的草案,我做给你看的,你可以处理这个问题,显然有很多东西可以添加或改进(将其应用于屏幕上不仅有2个但有许多方格的情况,或者在用户从屏幕释放手指时产生一种磁性效果等),但我希望至少它会把你放在正确的轨道为您的项目:)
太棒了!非常感谢你 – Yann