GameHandler.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using Windows.Devices.Geolocation;
  7. using Windows.Devices.Geolocation.Geofencing;
  8. using Windows.Foundation;
  9. using Windows.Services.Maps;
  10. using Windows.UI.Xaml.Media.Imaging;
  11. using YJMPD_UWP.Helpers;
  12. using YJMPD_UWP.Helpers.EventArgs;
  13. using YJMPD_UWP.Model.Object;
  14. using YJMPD_UWP.Views;
  15. namespace YJMPD_UWP.Model
  16. {
  17. public class GameHandler
  18. {
  19. public delegate void OnStatusUpdateHandler(object sender, GameStatusUpdatedEventArgs e);
  20. public event OnStatusUpdateHandler OnStatusUpdate;
  21. public delegate void OnPlayersUpdateHandler(object sender, GamePlayersUpdatedEventArgs e);
  22. public event OnPlayersUpdateHandler OnPlayersUpdate;
  23. public delegate void OnDestinationEnteredHandler(object sender, EventArgs e);
  24. public event OnDestinationEnteredHandler OnDestinationEnter;
  25. public delegate void OnDestinationLeftHandler(object sender, EventArgs e);
  26. public event OnDestinationLeftHandler OnDestinationLeave;
  27. public enum GameStatus { STARTED, SEARCHING, WAITING, ENDED, STOPPED }
  28. public GameStatus Status { get; private set; }
  29. public List<Player> Players { get; private set; }
  30. public BasicGeoposition Destination { get; private set; }
  31. public bool Selected { get; private set; }
  32. private void UpdateGameStatus(GameStatus status)
  33. {
  34. Status = status;
  35. if (Status == GameStatus.STARTED)
  36. App.Geo.KeepHistory();
  37. else
  38. App.Geo.ClearHistory();
  39. if (OnStatusUpdate == null) return;
  40. OnStatusUpdate(this, new GameStatusUpdatedEventArgs(status));
  41. }
  42. private void UpdateGamePlayers(Player player)
  43. {
  44. if (OnPlayersUpdate == null) return;
  45. OnPlayersUpdate(this, new GamePlayersUpdatedEventArgs(player));
  46. }
  47. private void UpdateDestinationEnter()
  48. {
  49. if (OnDestinationEnter == null) return;
  50. OnDestinationEnter(this, new EventArgs());
  51. }
  52. private void UpdateDestinationLeave()
  53. {
  54. if (OnDestinationLeave == null) return;
  55. OnDestinationLeave(this, new EventArgs());
  56. }
  57. public GameHandler()
  58. {
  59. Players = new List<Player>();
  60. Status = GameStatus.STOPPED;
  61. Selected = false;
  62. Destination = new BasicGeoposition() { Altitude = -1 };
  63. App.Photo.OnStatusUpdate += Photo_OnStatusUpdate;
  64. GeofenceMonitor.Current.GeofenceStateChanged += Current_GeofenceStateChanged;
  65. }
  66. private void Current_GeofenceStateChanged(GeofenceMonitor sender, object args)
  67. {
  68. if (Status != GameStatus.STARTED) return;
  69. var reports = sender.ReadReports();
  70. foreach (GeofenceStateChangeReport report in reports)
  71. {
  72. GeofenceState state = report.NewState;
  73. Geofence geofence = report.Geofence;
  74. if (geofence.Id != "destination") continue;
  75. else if (state == GeofenceState.Entered)
  76. {
  77. UpdateDestinationEnter();
  78. if (!Selected)
  79. App.Api.DestinationReached();
  80. }
  81. else if (state == GeofenceState.Exited)
  82. {
  83. UpdateDestinationLeave();
  84. if (Selected)
  85. Util.ShowToastNotification("Left Area", "Please return to your location!");
  86. }
  87. }
  88. }
  89. private void Photo_OnStatusUpdate(object sender, PhotoStatusUpdatedEventArgs e)
  90. {
  91. switch(e.Status)
  92. {
  93. case PhotoHandler.PhotoStatus.UPLOADING:
  94. App.Navigate(typeof(WaitingView), "Uploading...");
  95. break;
  96. case PhotoHandler.PhotoStatus.DONE:
  97. if(Selected)
  98. App.Api.SendPhoto(App.Photo.Photo);
  99. break;
  100. }
  101. }
  102. public void AddPlayer(string username)
  103. {
  104. Player p = new Player(username);
  105. Players.Add(p);
  106. UpdateGamePlayers(p);
  107. }
  108. public void SetSelected(bool b)
  109. {
  110. if (b)
  111. {
  112. Selected = true;
  113. Settings.Statistics.Selected += 1;
  114. }
  115. else
  116. Selected = false;
  117. }
  118. public void MoveToWaiting()
  119. {
  120. UpdateGameStatus(GameStatus.WAITING);
  121. }
  122. public void MoveToStarted(BasicGeoposition bgps)
  123. {
  124. App.Navigate(typeof(MatchView));
  125. Destination = bgps;
  126. GeofenceMonitor.Current.Geofences.Add(new Geofence("destination", new Geocircle(bgps, 50), MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited, false, TimeSpan.FromSeconds(1)));
  127. UpdateGameStatus(GameStatus.STARTED);
  128. }
  129. public void RemovePlayer(string username)
  130. {
  131. for(int i=Players.Count-1; i>=0; i--)
  132. {
  133. if (Players[i].Username == username)
  134. {
  135. UpdateGamePlayers(Players[i]);
  136. Players.RemoveAt(i);
  137. return;
  138. }
  139. }
  140. }
  141. public void Reset()
  142. {
  143. App.Photo.Reset();
  144. Selected = false;
  145. Destination = new BasicGeoposition() { Altitude = -1 };
  146. Players.Clear();
  147. GeofenceMonitor.Current.Geofences.Clear();
  148. UpdateGamePlayers(null);
  149. App.Navigate(typeof(GameView));
  150. }
  151. public void UpdatePlayer(string username, double pointstotal, double points)
  152. {
  153. foreach(Player p in Players)
  154. {
  155. if(p.Username == username)
  156. {
  157. p.Update(pointstotal, points);
  158. UpdateGamePlayers(p);
  159. return;
  160. }
  161. }
  162. }
  163. public Player GetPlayer(string username)
  164. {
  165. foreach(Player p in Players)
  166. {
  167. if(p.Username == username)
  168. return p;
  169. }
  170. return null;
  171. }
  172. //Ending
  173. public async Task<bool> StopMatch()
  174. {
  175. CalculateDistanceWalked();
  176. Settings.Statistics.Matches += 1;
  177. Settings.Statistics.AddPoints(GetPlayer(Settings.Username).Points);
  178. GeofenceMonitor.Current.Geofences.Clear();
  179. Selected = false;
  180. App.Navigate(typeof(ScoreView));
  181. UpdateGameStatus(GameStatus.ENDED);
  182. return true;
  183. }
  184. public async void CalculateDistanceWalked()
  185. {
  186. if (App.Geo.History.Count <= 1) return;
  187. MapRoute r = await Util.FindWalkingRoute(App.Geo.History.Select(p => p.Coordinate.Point).ToList());
  188. Settings.Statistics.Distance += r.LengthInMeters;
  189. }
  190. //Starting and Stopping
  191. public async Task<bool> StartGame()
  192. {
  193. UpdateGameStatus(GameStatus.SEARCHING);
  194. return await App.Api.JoinGame();
  195. }
  196. public async Task<bool> StopGame()
  197. {
  198. App.Api.LeaveGame();
  199. Reset();
  200. UpdateGameStatus(GameStatus.STOPPED);
  201. return true;
  202. }
  203. public void BackToGame()
  204. {
  205. switch(Status)
  206. {
  207. default:
  208. case GameStatus.STOPPED:
  209. break;
  210. case GameStatus.SEARCHING:
  211. App.Navigate(typeof(GameView));
  212. break;
  213. case GameStatus.WAITING:
  214. if (Selected)
  215. App.Navigate(typeof(PhotoView));
  216. else
  217. App.Navigate(typeof(WaitingView));
  218. break;
  219. case GameStatus.STARTED:
  220. App.Navigate(typeof(MatchView));
  221. break;
  222. case GameStatus.ENDED:
  223. App.Navigate(typeof(ScoreView));
  224. break;
  225. }
  226. }
  227. }
  228. }