powerfun-unity/Assets/TouchKit/TouchKit/Recognizers/TKAngleSwipeRecognizer.cs

175 lines
4.1 KiB
C#

using UnityEngine;
using System;
using System.Collections.Generic;
public class TKAngleSwipeRecognizer : TKAbstractGestureRecognizer
{
public event Action<TKAngleSwipeRecognizer> gestureRecognizedEvent;
private struct AngleListener
{
public float Varience;
public Vector2 Direction;
public Action<TKAngleSwipeRecognizer> Action;
public AngleListener (Vector2 direction, float varience, Action<TKAngleSwipeRecognizer> action) : this ()
{
Varience = varience;
Direction = direction;
Action = action;
}
}
private List<AngleListener> _angleRecognizedEvents = new List<AngleListener> ();
public float timeToSwipe = 0.5f;
public float swipeVelocity { get; private set; }
public float swipeAngle { get; private set; }
public Vector2 swipeVelVector { get; private set; }
public float minimumDistance = 2f;
// swipe state info
private Vector2 _startPoint;
private Vector2 _endPoint;
private float _startTime;
public Vector2 startPoint {
get { return this._startPoint; }
}
public Vector2 endPoint {
get { return this._endPoint; }
}
public TKAngleSwipeRecognizer () : this (2f)
{
}
public TKAngleSwipeRecognizer (float minimumDistanceCm)
{
minimumDistance = minimumDistanceCm;
}
public void addAngleRecogizedEvents (Action<TKAngleSwipeRecognizer> action, Vector2 direction, float angleVarience)
{
_angleRecognizedEvents.Add (new AngleListener (direction, angleVarience, action));
}
public void removeAngleRecognizedEvents (Action<TKAngleSwipeRecognizer> action)
{
_angleRecognizedEvents.RemoveAll (
(AngleListener listener) => {
return listener.Action == action;
});
}
public void removeAllAngleRecongnizedEvents ()
{
_angleRecognizedEvents.Clear ();
}
public void fireAngleRecognizedEvents ()
{
for (int i = 0, length = _angleRecognizedEvents.Count; i < length; i++)
{
var angleEvent = _angleRecognizedEvents [i];
if (angleEvent.Varience > Vector2.Angle (angleEvent.Direction, swipeVelVector))
{
angleEvent.Action (this);
}
}
}
private bool checkForSwipeCompletion (TKTouch touch)
{
// if we have a time stipulation and we exceeded it stop listening for swipes
if (timeToSwipe > 0.0f && (Time.time - _startTime) > timeToSwipe)
{
state = TKGestureRecognizerState.FailedOrEnded;
return false;
}
// Grab the total distance moved in both directions
var xDeltaAbsCm = Mathf.Abs (_startPoint.x - touch.position.x) / TouchKit.instance.ScreenPixelsPerCm;
var yDeltaAbsCm = Mathf.Abs (_startPoint.y - touch.position.y) / TouchKit.instance.ScreenPixelsPerCm;
_endPoint = touch.position;
// Get the velocity
swipeVelocity = Mathf.Sqrt (xDeltaAbsCm * xDeltaAbsCm + yDeltaAbsCm * yDeltaAbsCm);
// Calculate the movement vector
var displacement = endPoint - startPoint;
// Calculate the angle with respect to the x axis
swipeAngle = Mathf.Rad2Deg * Mathf.Atan2 (displacement.y, displacement.x);
// Get it between 0 to 360
if (swipeAngle < 0)
{
swipeAngle += 360;
}
swipeVelVector = _endPoint - _startPoint;
// If we have enough distance, then return true
if (swipeVelocity > minimumDistance)
{
return true;
}
return false;
}
internal override void fireRecognizedEvent ()
{
if (gestureRecognizedEvent != null)
{
gestureRecognizedEvent (this);
}
fireAngleRecognizedEvents ();
}
internal override bool touchesBegan (List<TKTouch> touches)
{
if (state == TKGestureRecognizerState.Possible)
{
_startPoint = touches [0].position;
_startTime = Time.time;
_trackingTouches.Add (touches [0]);
state = TKGestureRecognizerState.Began;
}
return false;
}
internal override void touchesMoved (List<TKTouch> touches)
{
if (state == TKGestureRecognizerState.Began)
{
if (checkForSwipeCompletion (touches [0]))
{
state = TKGestureRecognizerState.Recognized;
}
}
}
internal override void touchesEnded (List<TKTouch> touches)
{
state = TKGestureRecognizerState.FailedOrEnded;
}
public override string ToString ()
{
return string.Format ("{0}, velocity: {1}, angle: {2}, start point: {3}, end point: {4}",
base.ToString (), swipeVelocity, swipeAngle, startPoint, endPoint);
}
}