Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
Touch.cs
浏览该文件的文档.
1#if ANDROID
2using System.Collections.Concurrent;
3using Android.Views;
4#elif BROWSER
5using System.Collections.Concurrent;
6#endif
7
8namespace Engine.Input {
9 public static class Touch {
10#if ANDROID
11 public struct TouchInfo {
12 public int PointerId;
13 public Vector2 Position;
14 public int ActionMasked; //1: down, 2: move, 3: up
15
16 public TouchInfo(int pointerId, Vector2 position, int actionMasked) {
17 PointerId = pointerId;
18 Position = position;
19 ActionMasked = actionMasked;
20 }
21 }
22#endif
23
24 static List<TouchLocation> m_touchLocations = [];
25
26 public static ReadOnlyList<TouchLocation> TouchLocations => new(m_touchLocations);
27
28 public static event Action<TouchLocation> TouchPressed;
29
30 public static event Action<TouchLocation> TouchReleased;
31
32 public static event Action<TouchLocation> TouchMoved;
33
34 public static bool IsTouched;
35
36 internal static void Initialize() { }
37
38 internal static void Dispose() { }
39
40#if ANDROID
41 public static ConcurrentQueue<TouchInfo> m_cachedTouchEvents = [];
42 public static void EnqueueTouchEvent(int pointerId, Vector2 position, int actionMasked) => m_cachedTouchEvents.Enqueue(new TouchInfo(pointerId, position, actionMasked));
43 internal static void HandleTouchEvent(MotionEvent e) {
44#pragma warning disable CA1416
45 switch (e.ActionMasked) {
46 case MotionEventActions.Down:
47 case MotionEventActions.Pointer1Down:
48 m_cachedTouchEvents.Enqueue(
49 new TouchInfo(e.GetPointerId(e.ActionIndex), new Vector2(e.GetX(e.ActionIndex), e.GetY(e.ActionIndex)), 1)
50 ); break;
51 case MotionEventActions.Move:
52 for (int i = 0; i < e.PointerCount; i++) {
53 m_cachedTouchEvents.Enqueue(new TouchInfo(e.GetPointerId(i), new Vector2(e.GetX(i), e.GetY(i)), 2));
54 }
55 break;
56 case MotionEventActions.Up:
57 case MotionEventActions.Pointer1Up:
58 case MotionEventActions.Cancel:
59 case MotionEventActions.Outside:
60 m_cachedTouchEvents.Enqueue(
61 new TouchInfo(e.GetPointerId(e.ActionIndex), new Vector2(e.GetX(e.ActionIndex), e.GetY(e.ActionIndex)), 3)
62 ); break;
63 }
64#pragma warning restore CA1416
65 }
66#endif
67
68 public static void Clear() => m_touchLocations.Clear();
69
70 internal static void BeforeFrame() {
71#if ANDROID
72 while (!m_cachedTouchEvents.IsEmpty) {
73 if (m_cachedTouchEvents.TryDequeue(out TouchInfo touchInfo)) {
74 switch (touchInfo.ActionMasked) {
75 case 1: ProcessTouchPressed(touchInfo.PointerId, touchInfo.Position); break;
76 case 2: ProcessTouchMoved(touchInfo.PointerId, touchInfo.Position); break;
77 case 3: ProcessTouchReleased(touchInfo.PointerId, touchInfo.Position); break;
78 }
79 }
80 else {
81 Thread.Yield();
82 }
83 }
84#endif
85 }
86
87 internal static void AfterFrame() {
88 for (int i = 0; i < m_touchLocations.Count; i++) {
89 if (m_touchLocations[i].State == TouchLocationState.Released) {
90 m_touchLocations.RemoveAt(i);
91 continue;
92 }
93 if (m_touchLocations[i].ReleaseQueued) {
95 Id = m_touchLocations[i].Id, Position = m_touchLocations[i].Position, State = TouchLocationState.Released
96 };
97 }
98 else if (m_touchLocations[i].State == TouchLocationState.Pressed) {
100 Id = m_touchLocations[i].Id, Position = m_touchLocations[i].Position, State = TouchLocationState.Moved
101 };
102 }
103 }
104 }
105
106 static int FindTouchLocationIndex(int id) {
107 for (int i = 0; i < m_touchLocations.Count; i++) {
108 if (m_touchLocations[i].Id == id) {
109 return i;
110 }
111 }
112 return -1;
113 }
114
115 public static void ProcessTouchPressed(int id, Vector2 position) => ProcessTouchMoved(id, position);
116
117 public static void ProcessTouchMoved(int id, Vector2 position) {
118 if (!Window.IsActive
120 return;
121 }
122 IsTouched = true;
123 int num = FindTouchLocationIndex(id);
124 if (num >= 0) {
125 if (m_touchLocations[num].State == TouchLocationState.Moved) {
126 m_touchLocations[num] = new TouchLocation { Id = id, Position = position, State = TouchLocationState.Moved };
127 }
128 TouchMoved?.Invoke(m_touchLocations[num]);
129 }
130 else {
131 m_touchLocations.Add(new TouchLocation { Id = id, Position = position, State = TouchLocationState.Pressed });
132 TouchPressed?.Invoke(m_touchLocations[^1]);
133 }
134 }
135
136 public static void ProcessTouchReleased(int id, Vector2 position) {
137 if (!Window.IsActive
139 return;
140 }
141 int num = FindTouchLocationIndex(id);
142 if (num >= 0) {
143 if (m_touchLocations[num].State == TouchLocationState.Pressed) {
145 Id = id, Position = position, State = TouchLocationState.Pressed, ReleaseQueued = true
146 };
147 }
148 else {
149 m_touchLocations[num] = new TouchLocation { Id = id, Position = position, State = TouchLocationState.Released };
150 }
151 TouchReleased?.Invoke(m_touchLocations[num]);
152 }
153 }
154 }
155}
static bool IsKeyboardVisible
static void Clear()
static Action< TouchLocation > TouchPressed
static void AfterFrame()
static List< TouchLocation > m_touchLocations
static void Dispose()
static bool IsTouched
static Action< TouchLocation > TouchMoved
static ReadOnlyList< TouchLocation > TouchLocations
static void BeforeFrame()
static int FindTouchLocationIndex(int id)
static void ProcessTouchMoved(int id, Vector2 position)
static void ProcessTouchReleased(int id, Vector2 position)
static void Initialize()
static Action< TouchLocation > TouchReleased
static void ProcessTouchPressed(int id, Vector2 position)
static bool IsActive