UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Swipe diagonally to move node in SpriteKit

Forums > Swift

Apple's UISwipeGestureRecognizer is limited to up/down/left/right, but for my game I need to move in any direction with a swipe gesture. Further, I need to use the UITapGestureRecognizer but found that touchesMoved (used for swiping) conflicted with touchesEnded (used for tapping).

I turned to triganometry to try to solve the issue, which would hopfully give me the beginning and end coordinates so that I could ease/tween them:

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

  let touchTimeThreshold: CFTimeInterval = 0.3
        let touchDistanceThreshold: CGFloat = 1     // if the swipe distance is less then it is registered as a tap event
        var destination = CGPoint.zero
        var moveDistance: CGFloat = 20

        guard CACurrentMediaTime() - touchTime < touchTimeThreshold,
              let touch = touches.first else { return }

        let location = touch.location(in: self)

        let swipe = CGVector(dx: location.x - touchLocation.x, dy: location.y - touchLocation.y)
        let swipeLength = sqrt(swipe.dx * swipe.dx + swipe.dy * swipe.dy)

        guard swipeLength > touchDistanceThreshold else { return }
        let angle = atan2(swipe.dy, swipe.dx)   // convert the swipe vector to an angle

        //access the sprite node on the Entity
        guard let spriteComponent = hero.component(ofType: SpriteComponent.self) else { return }

                    if swipe.dy > 0 {

                destination.y = moveDistance
            } else {
                destination.y = -moveDistance
            }
                destination.x = spriteComponent.node.position.x +
                  ((destination.y - spriteComponent.node.position.y) / swipe.dy * swipe.dx)

           if swipe.dx > 0 {
                destination.x = moveDistance
            } else {
                destination.x = -moveDistance
            }
                destination.y = spriteComponent.node.position.y +
                  ((destination.x - spriteComponent.node.position.x) / swipe.dx * swipe.dy)

        spriteComponent.moveAnimation(theXAmount: destination.x, theYAmount: destination.y, theAnimation: "walkLeft")
}

The idea is not to register the point of which the swipe gesture finishes, nor for the gesture to need to touch the node, only that the gesture be made anywhere on screen and the node move a set distance.

The tap gesture will not need to move the node, that is a different option, but I will need the two working.

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.