Search code examples
sprite-kittimestamptouchesbegan

Sprite Kit - How to delay touchesBegan


The controls for my app are simple.

  • Touching the left side of the screen calls one function.
  • Touching the right side calls a second function. T
  • Touching both sides at the same time calls a third function.

The problem is, unless you touch the right and the left side of the screen at the exact same time the function for whichever side was touched first will be called. I'd like to be able to wait for a fraction of a second to see if the user is going to touch both sides of the screen before allowing the left or right functions to be called.

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

        for touch in touches {
            let location = touch.locationInView(nil)

            if location.x < self.size.width / 2 {
                touchingLeft = true
            }
            if location.x > self.size.width / 2 {
                touchingRight = true
            }

            if touchingRight && touchingLeft {
                ship.fireMain()

            //Wait for 1/10 of a second...

            } else if touchingLeft && !touchingRight {
                ship.fireLeft()
            } else if !touchingLeft && touchingRight {
                ship.fireRight()
            }
        }  
    }

Solution

  • To detect left, right, and left+right touches, simply perform the touch(es) test after a short delay. Here's an example of how to do that.

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        for touch in touches {
            let location = touch.locationInView(nil)
    
            if !touchingLeft && !touchingRight {
                // Adjust the delay as needed
                let delay = SKAction.waitForDuration(0.01)
                let test = SKAction.runBlock {
                    // Avoid retain cycle
                    [weak self] in
                    self?.testTouches()
                }
                let delayAndTest = SKAction.sequence([delay, test])
                runAction(delayAndTest)
            }
    
            if location.x < self.size.width / 2 {
                touchingLeft = true
            }
            else if location.x > self.size.width / 2 {
                touchingRight = true
            }
        }
    }
    
    func testTouches() {
        if touchingLeft && touchingRight {
            print("left+right")
        }
        else if touchingRight {
            print("right")
        }
        else {
            print("left")
        }
        touchingRight = false
        touchingLeft = false
    }