Search code examples
swiftsprite-kitnodesclickableremovechild

Swift SKSpriteNode will disappear but is still clickable


I have a problem with SpriteKit and Swift.

I'm adding SKSpriteNodes at different points of the code to the scene - some of them are clickable, some are not. I use the clickable Nodes as a Menu for the player. So, for example - if he clicks the InventoryButtonNode he jumps into the Inventory. In the Inventory he can touch the PlayButton and jumps back into the game. So, first i add the Nodes:

override func didMoveToView(view: SKView) {
    PlayButton = SKSpriteNode(imageNamed: "PlayButton")
    PlayButton.size = CGSize(width: 100, height: 100)
    PlayButton.position = CGPoint ... // not important
    PlayButton.zPosition = 200
    PlayButton.name = "PlayButton"
    self.addChild(PlayButton)
    InventoryButton = SKSpriteNode(imageNamed: "InventoryButton")
    InventoryButton.size = CGSize(width: 100, height: 100)
    InventoryButton.position = CGPoint ... // different position than PlayButton
    InventoryButton.zPosition = 200
    InventoryButton.name = "PlayButton"
    self.addChild(InventoryButton)

In the override func touchesBegan I use these "menu"-Nodes, here for example the InventoryButton-Node.

if InventoryButton.containsPoint(touch.locationInNode(self)) {
    print("Show Inventory")
    ShowInventory()
}

Now in the ShowInventory() function i want to remove those "menu"-Buttons from view so that i can add other nodes to show the Inventory of the Player.

func ShowInventory(){
    PlayButton.removeFromParent()
    InventoryButton.removeFromParent()
}

If I build and run this, the Nodes will be removed - or lets better say - they will get invisible.

Because, if i touch now at the position of InventoryButton I still get the print "Show Inventory" - so the function still reacts to my touch even if the node is not visible.

My problem is, that i have like 4 different functions like ShowInventory() .. I have ShowGame() and so on .. and i want in these functions to completely remove the Nodes and the "Touch"-Ability ..

I need a function which can remove the Nodes completely ..

I have even tried:

func ShowInventory(){
    self.removeAllChildren()
}

I get a grey Background without any nodes .. but still - if I touch where the Inventory Buttons position was i get the function called and the print "Show Inventory" ... it's frustrating.


Solution

  • It is because your check for which button is pressed does not take into account whether the button is visible.

    Even if a node has been removed from its parent, it still has a position and size. Those two properties are used by containsPoint: to determine if a point is in a node

    The easiest way to fix it would be to just check if the button has a parent node before checking to see if the button contains the point.

    if InventoryButton.parrent != nil && InventoryButton.containsPoint(touch.locationInNode(self)) {
        print("Show Inventory")
        ShowInventory()
    }