Tiptech
Tiptech

Reputation: 177

Disable touches everywhere except inside of a button? - Swift

When I die in my game, I want to ignore all touch events by the user EXCEPT if the user taps inside of or on the reset game button. Here is my code.

  for touch in touches{
        let location = touch.locationInNode(self)

        if died == true{
            Ball.physicsBody?.velocity = CGVectorMake(0, 0)
            if resetGame.containsPoint(location){

                restartScene()
                runAction(SKAction.playSoundFileNamed("Woosh.wav", waitForCompletion: false))

            }

            else  {


                self.userInteractionEnabled = false



            }

This is all inside of my touchesBegan. This was my attempt at ignoring the user's touch unless the location of the touch was within the size of button. How can I ignore a user's touches everywhere on the screen except the button? resetGame is an SKSpriteNode image.

Upvotes: 1

Views: 1725

Answers (1)

Alessandro Ornano
Alessandro Ornano

Reputation: 35392

There are two solutions to your issue.

The first case I want to propose to you is based to gesture recognizer. You can separate the button from the other touches events and switch on/off the touches event by a boolean var like this:

Gesture recognizers:

In the global var declaration section of your class:

var tapGesture :UITapGestureRecognizer!
var enableTouches:Bool = true

override func didMoveToView(view: SKView) {
        super.didMoveToView(view)
        self.tapGesture = UITapGestureRecognizer(target: self, action: #selector(GameClass.simpleTap(_:)))
        self.tapGesture.cancelsTouchesInView = false
        view.addGestureRecognizer(tapGesture)
        myBtn.name = "myBtn"
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
        return self.enableTouches
}

func simpleTap(sender: UITapGestureRecognizer) {
        print("simple tap")
        if sender.state == .Ended {
           var touchLocation: CGPoint = sender.locationInView(sender.view)
           touchLocation = self.convertPointFromView(touchLocation)
           let touchedNode = self.nodeAtPoint(touchLocation)
           // do your stuff
           if touchedNode.name == "myBtn" { 
              // button pressed, do your stuff
           }
        }
}

override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
       if died == true { 
            self.enableTouches = false // disable all touches but leave gestures enabled
            //do whatever you want when hero is died
       }
}

Only a Boolean

The second solution I want to propose is simply to stopping touches flow by using a simple boolean (it's not very elegant but it works). This method look when button is tapped and the update method check if your hero is dead so all touches will be disabled:

In the global var declaration section of your class:

var enableTouches:Bool = true

override func didMoveToView(view: SKView) {
            super.didMoveToView(view)
            myBtn.name = "myBtn"
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if (!enableTouches) {
            return
        }

        let touch = touches.first
        let positionInScene = touch!.locationInNode(self)
        let touchedNode = self.nodeAtPoint(positionInScene)
        // do your stuff
        if touchedNode.name == "myBtn" { 
           // button pressed, do your stuff
           if died == true { 
                self.enableTouches = false // disable all touches
                //do whatever you want when hero is died
           }
        }
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if (!enableTouches) {
            return
        }

        let touch = touches.first
        let positionInScene = touch!.locationInNode(self)
        let touchedNode = self.nodeAtPoint(positionInScene)
        // do your stuff

}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if (!enableTouches) {
            return
        }
}

The first case permit to you to have always the gesture enabled so you can do also other stuff with gestures when your hero will be died. The second case stop your touches when you press your button and do the "die flow". Choose which may be the most suitable for you.

Upvotes: 2

Related Questions