你知道益智游戏“voi”吗?这是一款与color-XOR逻辑兼容的游戏。这意味着:黑色+黑色=白色。
https://www.youtube.com/watch?v=Aw5BdVcAtII
有没有办法在sprit工具包中使用两个sprite节点进行相同的颜色逻辑?
感谢。
答案 0 :(得分:0)
当然,可以在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个但在屏幕上有很多方块的情况当用户从屏幕上松开手指等时,或创造一种磁效应,但我希望至少它会让你的项目走上正轨:)