How do I detect which SKSpriteNode has been touched

后端 未结 2 773
猫巷女王i
猫巷女王i 2020-11-28 14:35

I find a similar question, but I am trying to detect and identify which Sprite the user touch, and I don\'t know how to do that. This is my variable:

var sp         


        
相关标签:
2条回答
  • 2020-11-28 15:19

    First, you need another way to create the sprite, here are a way:

    let spriteA = SKSpriteNode(imageNamed: "a")
    scene.addChild(spriteA)
    let spriteB = SKSPriteNode(imageNamed: "b")
    scene.addChild(spriteB)
    ...and so on...
    

    Now we needs to set a name for the sprite so we can know which node is tapped later. To add a name for a sprite just do this:

    spriteNode.name = "name of the sprite"
    

    Putting this code in the above example will look something like this:

    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...
    

    To detect touches put this into your SKScene subclass:

    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
    }
    

    The targetNode is the node you tapped.

    If you wants to get the name of the sprite you can use targetNode.name.

    0 讨论(0)
  • 2020-11-28 15:38

    What you are trying to do (even if I don't see a reason for this) can be accomplished using delegation pattern. Basically, you will tell your delegate (the scene, or whatever you set as a delegate) to do something for you, and you will do that directly from within the button's touchesBegan method. Also, you will pass the button's name to a scene.

    To make this happen, first you have to define a protocol called ButtonDelegate. That protocol defines a requirement which states that any conforming class has to implement a method called printButtonsName(_:):

    protocol ButtonDelegate:class {
    
       func printButtonsName(name:String?)
    }
    

    This is the method which will be implemented in your GameSceneclass, but called from within button's touchesBegan. Also, this method will be used to pass a button's name to its delegate (scene), so you will always know which button is tapped.

    Next thing is button class itself. Button might look like this:

    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)
        }  
    }
    

    The important thing here is userInteractionEnabled = true, which means that button will accept touches. Another important thing is a delegate property. As already mentioned, buttons will have the scene set as their delegate. Setting a scene as delegate of buttons will be done later when we create some buttons... To make this easier for you, think of a delegate as a worker who works for his boss :) The boss (a button) tells his worker (a scene) to do something for him (to prints his name).

    Okay, so lets make sure that scene conforms to a ButtonDelegate protocol...Why is this important? It is important because the worker (scene) must follow the orders of his boss (a button). By conforming to this protocol, the worker is making a contract with his boss where confirming that he knows how to do his job and will follow his orders :)

    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)
        }
    }
    

    And that's it. When you tap the play button, the touchesBegan on a button itself will be called, then the button will tell its delegate to print its name using the method defined inside of scene class.

    0 讨论(0)
提交回复
热议问题