Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
SwipeGestureRecognizer.cs
1using System.Drawing;
3
5
20public sealed class SwipeGestureRecognizer : IDisposable
21{
22 private readonly ITouchInput _touchInput;
23 private readonly Dictionary<int, SwipeState> _activeSwipes = new();
24 private readonly HashSet<int> _activeContacts = new();
25 private bool _isMultiTouchSequence;
26 private bool _isDisposed;
27
33 public double MinimumSwipeSpeedPixelsPerSecond { get; set; } = 200;
34
40 public double MinimumSwipeDistancePixels { get; set; } = 30;
41
45 public event EventHandler<SwipedEventArgs>? Swiped;
46
58 {
59 _touchInput = touchInput ?? throw new ArgumentNullException(nameof(touchInput));
60 _touchInput.TouchBegan += OnTouchBegan;
61 _touchInput.TouchEnded += OnTouchEnded;
62 }
63
64 private void OnTouchBegan(object? sender, TouchEventArgs e)
65 {
66 _activeContacts.Add(e.Touch.Id);
67
68 if (_activeContacts.Count > 1)
69 {
70 _isMultiTouchSequence = true;
71 _activeSwipes.Clear();
72 return;
73 }
74
75 if (!_isMultiTouchSequence)
76 _activeSwipes[e.Touch.Id] = new SwipeState(e.Touch.Position, e.Tick);
77 }
78
79 private void OnTouchEnded(object? sender, TouchEventArgs e)
80 {
81 _activeContacts.Remove(e.Touch.Id);
82
83 if (_isMultiTouchSequence)
84 {
85 _activeSwipes.Remove(e.Touch.Id);
86 if (_activeContacts.Count == 0)
87 _isMultiTouchSequence = false;
88 return;
89 }
90
91 if (!_activeSwipes.TryGetValue(e.Touch.Id, out var state))
92 return;
93
94 _activeSwipes.Remove(e.Touch.Id);
95
96 // A system-cancelled contact must never produce a swipe.
97 if (e.Touch.Phase == TouchPhase.Cancelled)
98 return;
99
100 var endPos = e.Touch.Position;
101 var dx = endPos.X - state.StartPosition.X;
102 var dy = endPos.Y - state.StartPosition.Y;
103
104 var distance = Math.Sqrt(dx * dx + dy * dy);
105 var elapsed = HighResTimer.GetDuration(state.StartTick, e.Tick);
106
107 if (elapsed <= 0)
108 return;
109
110 var speed = distance / elapsed;
111
112 if (!WouldRecognize(distance, elapsed))
113 return;
114
115 var direction = Math.Abs(dx) >= Math.Abs(dy)
116 ? (dx >= 0 ? SwipeDirection.Right : SwipeDirection.Left)
117 : (dy >= 0 ? SwipeDirection.Down : SwipeDirection.Up);
118
119 Swiped?.Invoke(this, new SwipedEventArgs(direction, state.StartPosition, endPos, speed));
120 }
121
126 public void Dispose()
127 {
128 if (_isDisposed) return;
129 _isDisposed = true;
130
131 _touchInput.TouchBegan -= OnTouchBegan;
132 _touchInput.TouchEnded -= OnTouchEnded;
133 Reset();
134 }
135
136 internal void Reset()
137 {
138 _activeSwipes.Clear();
139 _activeContacts.Clear();
140 _isMultiTouchSequence = false;
141 }
142
143 internal bool WouldRecognize(double distance, double elapsedSeconds)
144 => elapsedSeconds > 0 &&
145 distance >= MinimumSwipeDistancePixels &&
146 distance / elapsedSeconds >= MinimumSwipeSpeedPixelsPerSecond;
147
148 private readonly record struct SwipeState(Point StartPosition, long StartTick);
149}
SwipeGestureRecognizer(ITouchInput touchInput)
Initializes a new instance of the SwipeGestureRecognizer class, subscribing to touch events from the ...
double MinimumSwipeDistancePixels
Gets or sets the minimum straight-line travel distance required for a swipe. This prevents a short,...
EventHandler< SwipedEventArgs >? Swiped
Occurs when a qualifying swipe gesture is detected.
void Dispose()
Releases all resources held by this recognizer and unsubscribes from the touch input source....
double MinimumSwipeSpeedPixelsPerSecond
Gets or sets the minimum average speed, in pixels per second, that a touch must reach when it ends in...
Provides data for touch contact events raised by ITouchInput, including the touch point and engine ti...
TouchPoint Touch
Gets the touch contact point associated with this event.
long Tick
Gets the engine tick at which this touch event was emitted.
Represents a touch input source that tracks active contact points and raises lifecycle events when fi...
SwipeDirection
Specifies the direction of a swipe gesture.
@ Down
The swipe moved primarily downward (positive Y axis in screen coordinates).
@ Up
The swipe moved primarily upward (negative Y axis in screen coordinates).
TouchPhase
Describes the current phase of a single touch contact point in its lifecycle.
Definition TouchPhase.cs:7