如何检测触摸了哪个 SKSpriteNode
How do I detect which SKSpriteNode has been touched
我找到了 ,但我正在尝试检测和识别用户触摸了哪个 Sprite,但我不知道该怎么做。这是我的变量:
var sprites: [[SKSpriteNode]] = [[SKSpriteNode(imageNamed: "a"), SKSpriteNode(imageNamed: "b")], [SKSpriteNode(imageNamed: "c"),SKSpriteNode(imageNamed: "d")]]
我的想法是识别 spriteNode 然后用其他 sprite 替换它或改变颜色,但我不知道如何用这个 spriteNodes 矩阵来做,我想第一步是识别 sprite .
首先,您需要另一种创建精灵的方法,这里有一种方法:
let spriteA = SKSpriteNode(imageNamed: "a")
scene.addChild(spriteA)
let spriteB = SKSPriteNode(imageNamed: "b")
scene.addChild(spriteB)
...and so on...
现在我们需要为精灵设置一个名称,这样我们就可以知道稍后点击了哪个节点。要为精灵添加名称,只需执行以下操作:
spriteNode.name = "name of the sprite"
将此代码放在上面的示例中将如下所示:
let spriteA = SKSpriteNode(imageNamed: "a")
spriteA.name = "a"
scene.addChild(spriteA)
let spriteB = SKSPriteNode(imageNamed: "b")
spriteB.name = "b"
scene.addChild(spriteB)
...and so on...
要检测触摸,请将其放入您的 SKScene 子类中:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first as UITouch!
let touchLocation = touch.locationInNode(self)
let targetNode = nodeAtPoint(touchLocation) as! SKSpriteNode
}
targetNode
是您点击的节点。
如果你想得到精灵的名字你可以使用targetNode.name
。
可以使用 delegation 模式来完成您正在尝试做的事情(即使我没有看到这样做的原因)。基本上,您将告诉您的委托(场景,或您设置为委托的任何内容)为您做某事,您将直接从按钮的 touchesBegan
方法中执行此操作。此外,您会将按钮的名称传递给场景。
要做到这一点,首先您必须定义一个名为 ButtonDelegate
的协议。该协议定义了一项要求,该要求规定任何符合要求的 class 都必须实现一个名为 printButtonsName(_:)
:
的方法
protocol ButtonDelegate:class {
func printButtonsName(name:String?)
}
这是将在您的 GameScene
class 中实现的方法,但从按钮的 touchesBegan
中调用。此外,此方法将用于将按钮的名称传递给它的委托(场景),因此您将始终知道点击了哪个按钮。
接下来是按钮 class 本身。 Button
可能看起来像这样:
class Button : SKSpriteNode{
weak var delegate:ButtonDelegate?
init(name:String){
super.init(texture: nil, color: .purpleColor(), size: CGSize(width: 50, height: 50))
self.name = name
self.userInteractionEnabled = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
delegate?.printButtonsName(self.name)
}
}
这里重要的是userInteractionEnabled = true
,这意味着按钮将接受触摸。另一个重要的事情是 delegate
属性。如前所述,按钮会将场景设置为它们的代表。将场景设置为按钮的代表将在稍后创建一些按钮时完成......为了让您更容易,将代表视为为其老板工作的工人:)老板(一个按钮)告诉他的工人(一个场景)为他做点什么(打印他的名字)。
好的,让我们确保场景符合 ButtonDelegate
协议...为什么这很重要?这很重要,因为工人(场景)必须服从老板(一个按钮)的命令。通过遵守此协议,该工人正在与他的老板签订合同,确认他知道如何做他的工作并将服从他的命令:)
class GameScene: SKScene, ButtonDelegate {
override func didMoveToView(view: SKView) {
let play = Button(name:"play")
play.delegate = self
let stop = Button(name:"stop")
stop.delegate = self
play.position = CGPoint(x: frame.midX - 50.0, y: frame.midY)
stop.position = CGPoint(x: frame.midX + 50.0, y: frame.midY)
addChild(play)
addChild(stop)
}
func printButtonsName(name: String?) {
if let buttonName = name {
print("Pressed button : \(buttonName) ")
}
//Use switch here to take appropriate actions based on button's name (if you like)
}
}
就是这样。当您点击播放按钮时,按钮本身的 touchesBegan
将被调用,然后该按钮将告诉其委托使用场景中定义的方法打印其名称 class.
我找到了
var sprites: [[SKSpriteNode]] = [[SKSpriteNode(imageNamed: "a"), SKSpriteNode(imageNamed: "b")], [SKSpriteNode(imageNamed: "c"),SKSpriteNode(imageNamed: "d")]]
我的想法是识别 spriteNode 然后用其他 sprite 替换它或改变颜色,但我不知道如何用这个 spriteNodes 矩阵来做,我想第一步是识别 sprite .
首先,您需要另一种创建精灵的方法,这里有一种方法:
let spriteA = SKSpriteNode(imageNamed: "a")
scene.addChild(spriteA)
let spriteB = SKSPriteNode(imageNamed: "b")
scene.addChild(spriteB)
...and so on...
现在我们需要为精灵设置一个名称,这样我们就可以知道稍后点击了哪个节点。要为精灵添加名称,只需执行以下操作:
spriteNode.name = "name of the sprite"
将此代码放在上面的示例中将如下所示:
let spriteA = SKSpriteNode(imageNamed: "a")
spriteA.name = "a"
scene.addChild(spriteA)
let spriteB = SKSPriteNode(imageNamed: "b")
spriteB.name = "b"
scene.addChild(spriteB)
...and so on...
要检测触摸,请将其放入您的 SKScene 子类中:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first as UITouch!
let touchLocation = touch.locationInNode(self)
let targetNode = nodeAtPoint(touchLocation) as! SKSpriteNode
}
targetNode
是您点击的节点。
如果你想得到精灵的名字你可以使用targetNode.name
。
可以使用 delegation 模式来完成您正在尝试做的事情(即使我没有看到这样做的原因)。基本上,您将告诉您的委托(场景,或您设置为委托的任何内容)为您做某事,您将直接从按钮的 touchesBegan
方法中执行此操作。此外,您会将按钮的名称传递给场景。
要做到这一点,首先您必须定义一个名为 ButtonDelegate
的协议。该协议定义了一项要求,该要求规定任何符合要求的 class 都必须实现一个名为 printButtonsName(_:)
:
protocol ButtonDelegate:class {
func printButtonsName(name:String?)
}
这是将在您的 GameScene
class 中实现的方法,但从按钮的 touchesBegan
中调用。此外,此方法将用于将按钮的名称传递给它的委托(场景),因此您将始终知道点击了哪个按钮。
接下来是按钮 class 本身。 Button
可能看起来像这样:
class Button : SKSpriteNode{
weak var delegate:ButtonDelegate?
init(name:String){
super.init(texture: nil, color: .purpleColor(), size: CGSize(width: 50, height: 50))
self.name = name
self.userInteractionEnabled = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
delegate?.printButtonsName(self.name)
}
}
这里重要的是userInteractionEnabled = true
,这意味着按钮将接受触摸。另一个重要的事情是 delegate
属性。如前所述,按钮会将场景设置为它们的代表。将场景设置为按钮的代表将在稍后创建一些按钮时完成......为了让您更容易,将代表视为为其老板工作的工人:)老板(一个按钮)告诉他的工人(一个场景)为他做点什么(打印他的名字)。
好的,让我们确保场景符合 ButtonDelegate
协议...为什么这很重要?这很重要,因为工人(场景)必须服从老板(一个按钮)的命令。通过遵守此协议,该工人正在与他的老板签订合同,确认他知道如何做他的工作并将服从他的命令:)
class GameScene: SKScene, ButtonDelegate {
override func didMoveToView(view: SKView) {
let play = Button(name:"play")
play.delegate = self
let stop = Button(name:"stop")
stop.delegate = self
play.position = CGPoint(x: frame.midX - 50.0, y: frame.midY)
stop.position = CGPoint(x: frame.midX + 50.0, y: frame.midY)
addChild(play)
addChild(stop)
}
func printButtonsName(name: String?) {
if let buttonName = name {
print("Pressed button : \(buttonName) ")
}
//Use switch here to take appropriate actions based on button's name (if you like)
}
}
就是这样。当您点击播放按钮时,按钮本身的 touchesBegan
将被调用,然后该按钮将告诉其委托使用场景中定义的方法打印其名称 class.