swift matrix sprite-kit touch skspritenode

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 .