bluelemonade
bluelemonade

Reputation: 1295

spritekit make childnode not touchable

I have a menu button (skSpriteNode) and a small play icon inside this sprite

mainButton.addChild (playIcon)
mainButton.name = "xyz"
addchild (mainButton)

ok, I gave the button the name to check if a sprite with this name is touched.

when I touch the icon child inside the button, the touchedNode.name is nil. I set isUserInteractionEnabled = false for the icon child. I want to pass the touch to the parent. how can I do this.

  for touch in touches {

            let location = touch.location(in: self)
            let touchedNode  = self.atPoint(location)

            if (touchedNode.name != nil) {
                print ("node \(touchedNode.name!)")
            } else {
                continue
            }
 }

Upvotes: 2

Views: 428

Answers (2)

bluelemonade
bluelemonade

Reputation: 1295

I implemented the button Touchbegan and tried to implement a subclass for a slider with a background and the child thumb inside the slider. I added the sliderDelegate Protocoll in my GameScene. the down touch is ok, but I didn't get the moved in

import Foundation
import SpriteKit


protocol SliderDelegate:class {

    func touchesBeganSKSpriteNodeSlider(name:String?, location: CGPoint?)
    func touchesMovedSKSpriteNodeSlider(name:String?, location: CGPoint?)
    func touchesEndedSKSpriteNodeSlider(name:String?, location: CGPoint?)

}


class SKSpriteNodeSlider : SKSpriteNode{

    weak var delegate:SliderDelegate?

    init(imageNamed: String){

        // super.init(imageNamed: imageNamed)
        let texture = SKTexture(imageNamed: imageNamed)
        super.init(texture: texture, color: .white, size: texture.size())
        // self.name = name
        self.isUserInteractionEnabled = true
        // let icon = SKSpriteNode(color: .white, size: CGSize(width:100, height:100))
        // addChild(icon)
    }

    required init?(coder aDecoder: NSCoder) {

        fatalError("init(coder:) has not been implemented")

    }


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        // for touch in touches {
        if let touch = touches.first {
            let loc = touch.location(in: self)
            delegate?.touchesBeganSKSpriteNodeSlider(name: self.name, location: loc)

        }

    }


    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        print ("touchesMoved")

        // for touch in touches {
        if let touch = touches.first {
            let loc = touch.location(in: self)
            delegate?.touchesMovedSKSpriteNodeSlider(name: self.name, location: loc)
         }

    }


    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let loc = touch.location(in: self)
            delegate?.touchesEndedSKSpriteNodeSlider(name: self.name, location: loc)
        }

    }

}

Upvotes: 1

Whirlwind
Whirlwind

Reputation: 13665

You have to implement touchesBegan in a subclass of SKSpriteNode and to set its isUserInteractionEnabled = true, in order to accept and process the touches for that particular node (button).

import SpriteKit

protocol ButtonDelegate:class {

    func printButtonsName(name:String?)
}

class Button : SKSpriteNode{

    weak var delegate:ButtonDelegate?

    init(name:String){
        super.init(texture: nil, color: .purple, size: CGSize(width: 250, height: 250))
        self.name = name
        self.isUserInteractionEnabled = true
        let icon = SKSpriteNode(color: .white, size: CGSize(width:100, height:100))
        addChild(icon)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {



        delegate?.printButtonsName(name: self.name)
    }  
}

class GameScene: SKScene, ButtonDelegate {

    override func didMove(to view: SKView) {

        let button = Button(name:"xyz")
        button.delegate = self


        button.position = CGPoint(x: frame.midX - 50.0, y: frame.midY)


        addChild(button)

    }

    func printButtonsName(name: String?) {

        if let buttonName = name {
            print("Pressed button : \(buttonName) ")
        }
    }
}

Now, this button will swallow the touches and the icon sprite will be ignored.

I just modified the code from one of my answers to make an example specific to your needs, but you can read, in that link, about whole thing more in detail if interested.

Upvotes: 5

Related Questions