swift - ¿Cómo detecto qué SKSpriteNode ha sido tocado?
matrix sprite-kit (2)
Encuentro una pregunta similar , pero estoy tratando de detectar e identificar qué Sprite toca el usuario, y no sé cómo hacerlo. Esta es mi variable:
var sprites: [[SKSpriteNode]] = [[SKSpriteNode(imageNamed: "a"), SKSpriteNode(imageNamed: "b")], [SKSpriteNode(imageNamed: "c"),SKSpriteNode(imageNamed: "d")]]
La idea es identificar el spriteNode y luego reemplazarlo por otro sprite o cambiar el color, pero no sé cómo hacerlo con esta matriz de spriteNodes, supongo que el primer paso es identificar el sprite.
Lo que está tratando de hacer (incluso si no veo una razón para esto) se puede lograr utilizando un patrón de
delegation
.
Básicamente, le dirá a su delegado (la escena, o lo que sea que establezca como delegado) que haga algo por usted, y lo hará directamente desde el método de
touchesBegan
de
touchesBegan
del botón.
Además, pasará el nombre del botón a una escena.
Para que esto suceda, primero debe definir un protocolo llamado
ButtonDelegate
.
Ese protocolo define un requisito que establece que cualquier clase conforme tiene que implementar un método llamado
printButtonsName(_:)
:
protocol ButtonDelegate:class {
func printButtonsName(name:String?)
}
Este es el método que se implementará en su clase
GameScene
, pero se llama desde el botón
touchesBegan
.
Además, este método se utilizará para pasar el nombre de un botón a su delegado (escena), para que siempre sepa qué botón está pulsado.
Lo siguiente es la clase de botón en sí.
Button
podría verse así:
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)
}
}
Lo importante aquí es
userInteractionEnabled = true
, lo que significa que el botón aceptará toques.
Otra cosa importante es una propiedad
delegate
.
Como ya se mencionó, los botones tendrán la escena configurada como su delegado.
La configuración de una escena como delegado de botones se realizará más adelante cuando creamos algunos botones ... Para que sea más fácil para usted, piense en un delegado como un trabajador que trabaja para su jefe :) El jefe (un botón) le dice a su trabajador ( una escena) para hacer algo por él (para imprimir su nombre).
Bien, entonces
ButtonDelegate
que la escena se ajusta a un protocolo
ButtonDelegate
... ¿Por qué es esto importante?
Es importante porque el trabajador (escena) debe seguir las órdenes de su jefe (un botón).
Al cumplir con este protocolo, el trabajador está haciendo un contrato con su jefe donde confirma que sabe cómo hacer su trabajo y seguirá sus órdenes :)
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)
}
}
Y eso es.
Cuando toca el botón de reproducción, se
touchesBegan
los
touchesBegan
en un botón, luego el botón le indicará a su delegado que imprima su nombre usando el método definido dentro de la clase de escena.
Primero, necesitas otra forma de crear el sprite, aquí hay una manera:
let spriteA = SKSpriteNode(imageNamed: "a")
scene.addChild(spriteA)
let spriteB = SKSPriteNode(imageNamed: "b")
scene.addChild(spriteB)
...and so on...
Ahora necesitamos establecer un nombre para el sprite para que podamos saber qué nodo se toca más adelante. Para agregar un nombre para un sprite solo haz esto:
spriteNode.name = "name of the sprite"
Poner este código en el ejemplo anterior se verá así:
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...
Para detectar toques ponga esto en su subclase 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
es el nodo que tocó.
Si desea obtener el nombre del sprite, puede usar
targetNode.name
.