I want to calculate the delta between a swipe gesture or dragging gesture. what I want to do is to get this delta and then to use it as velocity (by adding time var). I really get confused about how should I do this - via touchesMoved
or via UIPanGestureRecognizer
. also, I don't really understand the difference between them. right now I set and get the first touch on the screen but I don't know how to get the last one so I can calculate the vector. can anyone help me with that?
right now I'm doing that via touchesBega
n and touchesEnded
, I'm not sure if its the right and the better way, here is my code so far:
class GameScene: SKScene {
var start: CGPoint?
var end: CGPoint?
override func didMove(to view: SKView) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {return}
self.start = touch.location(in: self)
print("start point: ", start!)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {return}
self.end = touch.location(in: self)
print("end point: ", end!)
let deltax:CGFloat = ((self.start?.x)! - (self.end?.x)!)
let deltay:CGFloat = ((self.start?.y)! - (self.end?.y)!)
print(UInt(deltax))
print(UInt(deltay))
}
You can detect swipe gestures using the built-in touch handlers of SpriteKit or you can implement a UISwipeGestureRecognizer
. The following is an example of how to detect swipe gestures using SpriteKit's touch handlers:
First, define the variables and constants...
Define the starting point and time of the initial touch.
var touchStart: CGPoint?
var startTime : TimeInterval?
Define constants that specify the characteristics of the swipe gesture. By changing these constants, you can detect the difference between a swipe, drag, or flick.
let minSpeed:CGFloat = 1000
let maxSpeed:CGFloat = 5000
let minDistance:CGFloat = 25
let minDuration:TimeInterval = 0.1
In touchesBegan
, store the starting point and time of the initial touch
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touchStart = touches.first?.location(in: self)
startTime = touches.first?.timestamp
}
In touchesEnded
, calculate the gesture's distance, duration, and speed. Compare these value against the constants to determine if the gesture was a swipe.
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touchStart = self.touchStart else {
return
}
guard let startTime = self.startTime else {
return
}
guard let location = touches.first?.location(in: self) else {
return
}
guard let time = touches.first?.timestamp else {
return
}
var dx = location.x - touchStart.x
var dy = location.y - touchStart.y
// Distance of the gesture
let distance = sqrt(dx*dx+dy*dy)
if distance >= minDistance {
// Duration of the gesture
let deltaTime = time - startTime
if deltaTime > minDuration {
// Speed of the gesture
let speed = distance / CGFloat(deltaTime)
if speed >= minSpeed && speed <= maxSpeed {
// Normalize by distance to obtain unit vector
dx /= distance
dy /= distance
// Swipe detected
print("Swipe detected with speed = \(speed) and direction (\(dx), \(dy)")
}
}
}
// Reset variables
touchStart = nil
startTime = nil
}