Reputation: 3677
I am trying to hit a ball on the left and right side of a box with a speed depends upon the shake gesture speed/acceleration.
I am unable to get this i have tried many thing but i cannot get the speed/acceleration of gesture. I detect the gesture with core motion as well as with motionBegun
and motionEnded
method but unable to detect the speed so that i could create a logic of hitting the ball on both side of a box.
Here is my code that how i detect the direction of shake with CoreMotion
and shake gesture detection with motionBegun
and motionEnded
var startedLeftTilt = false
var startedRightTilt = false
var dateLastShake = NSDate(timeIntervalSinceNow: -2)
var dateStartedTilt = NSDate(timeIntervalSinceNow: -2)
var motionManager = CoreMotion.CMMotionManager()
let tresholdFirstMove = 3.0
let tresholdBackMove = 0.5
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
motionManager.startGyroUpdates(to: OperationQueue.current!, withHandler: { (gyroData, error) -> Void in
self.handleGyroData(rotation: (gyroData?.rotationRate)!)
})
}
private func handleGyroData(rotation: CMRotationRate) {
if fabs(rotation.z) > tresholdFirstMove && fabs(dateLastShake.timeIntervalSinceNow) > 0.3
{
if !startedRightTilt && !startedLeftTilt
{
dateStartedTilt = NSDate()
if (rotation.z > 0)
{
startedLeftTilt = true
startedRightTilt = false
}
else
{
startedRightTilt = true
startedLeftTilt = false
}
}
}
if fabs(dateStartedTilt.timeIntervalSinceNow) >= 0.3
{
startedRightTilt = false
startedLeftTilt = false
}
else
{
if (fabs(rotation.z) > tresholdBackMove)
{
if startedLeftTilt && rotation.z < 0
{
dateLastShake = NSDate()
startedRightTilt = false
startedLeftTilt = false
}
else if startedRightTilt && rotation.z > 0
{
dateLastShake = NSDate()
startedRightTilt = false
startedLeftTilt = false
}
}
}
}
override func becomeFirstResponder() -> Bool {
return true
}
override func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) {
if motion == .motionShake {
NSLog("Motion is Started");
}
}
override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) {
if motion == .motionShake {
NSLog("Motion is Ended");
}
}
override func viewDidLoad() {
super.viewDidLoad()
motionManager.gyroUpdateInterval = 0.01
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Upvotes: 1
Views: 1270
Reputation: 108
Use gyro
and motion
at the same time to get your trigger. Gyro will provide you the direction and motion will provide you some kind of speed analysis.
Implementing both at the same time with your custom logic will you what exactly you are trying to get.
Use the last answer for finding the direction.
StackAnswer
Upvotes: 1
Reputation: 131398
Core motion has lots of options. You can use high level events like shake events, or you can get gyro or acellerometer updates.
The code you posted is monitoring gyro events. If you're looking for the force of a shake you want acellerometer events, not gyro events.
Upvotes: 2