You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Game.cs 13 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. using System;
  2. using System.Threading;
  3. using System.Collections.Generic;
  4. using GameClass.GameObj;
  5. using Preparation.Utility;
  6. using Timothy.FrameRateTask;
  7. using Preparation.Interface;
  8. namespace Gaming
  9. {
  10. public partial class Game
  11. {
  12. public struct PlayerInitInfo
  13. {
  14. public uint birthPointIndex;
  15. public long teamID;
  16. public long playerID;
  17. public CharacterType characterType;
  18. public ActiveSkillType commonSkill;
  19. public PlayerInitInfo(uint birthPointIndex, long teamID, long playerID, CharacterType characterType, ActiveSkillType commonSkill)
  20. {
  21. this.birthPointIndex = birthPointIndex;
  22. this.teamID = teamID;
  23. this.characterType = characterType;
  24. this.commonSkill = commonSkill;
  25. this.playerID = playerID;
  26. }
  27. }
  28. private readonly List<Team> teamList;
  29. public List<Team> TeamList => teamList;
  30. private readonly Map gameMap;
  31. public Map GameMap => gameMap;
  32. // private readonly int numOfTeam;
  33. public long AddPlayer(PlayerInitInfo playerInitInfo)
  34. {
  35. if (!Team.teamExists(playerInitInfo.teamID))
  36. /* || !MapInfo.ValidBirthPointIdx(playerInitInfo.birthPointIdx)
  37. || gameMap.BirthPointList[playerInitInfo.birthPointIdx].Parent != null)*/
  38. return GameObj.invalidID;
  39. XY pos = gameMap.BirthPointList[playerInitInfo.birthPointIndex].Position;
  40. // Console.WriteLine($"x,y: {pos.x},{pos.y}");
  41. Character newPlayer = new(pos, GameData.characterRadius, gameMap.GetPlaceType(pos), playerInitInfo.characterType, playerInitInfo.commonSkill);
  42. gameMap.BirthPointList[playerInitInfo.birthPointIndex].Parent = newPlayer;
  43. gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
  44. try
  45. {
  46. gameMap.GameObjDict[GameObjType.Character].Add(newPlayer);
  47. }
  48. finally
  49. {
  50. gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
  51. }
  52. // Console.WriteLine($"GameObjDict[GameObjType.Character] length:{gameMap.GameObjDict[GameObjType.Character].Count}");
  53. teamList[(int)playerInitInfo.teamID].AddPlayer(newPlayer);
  54. newPlayer.TeamID = playerInitInfo.teamID;
  55. newPlayer.PlayerID = playerInitInfo.playerID;
  56. /*new Thread //人物装弹
  57. (
  58. () =>
  59. {
  60. while (!gameMap.Timer.IsGaming)
  61. Thread.Sleep(newPlayer.CD);
  62. long lastTime = Environment.TickCount64;
  63. new FrameRateTaskExecutor<int>(
  64. loopCondition: () => gameMap.Timer.IsGaming,
  65. loopToDo: () =>
  66. {
  67. if (!newPlayer.IsResetting)
  68. {
  69. long nowTime = Environment.TickCount64;
  70. if (newPlayer.BulletNum == newPlayer.MaxBulletNum)
  71. lastTime = nowTime;
  72. if (nowTime - lastTime >= newPlayer.CD)
  73. {
  74. _ = newPlayer.TryAddBulletNum();
  75. lastTime = nowTime;
  76. }
  77. }
  78. },
  79. timeInterval: GameData.checkInterval,
  80. finallyReturn: () => 0
  81. )
  82. {
  83. AllowTimeExceed = true
  84. MaxTolerantTimeExceedCount = 5,
  85. TimeExceedAction = exceedTooMuch =>
  86. {
  87. if (exceedTooMuch) Console.WriteLine("The computer runs too slow that it cannot check the color below the player in time!");
  88. }
  89. }
  90. .Start();
  91. }
  92. )
  93. { IsBackground = true }.Start();*/
  94. return newPlayer.ID;
  95. }
  96. public bool StartGame(int milliSeconds)
  97. {
  98. if (gameMap.Timer.IsGaming)
  99. return false;
  100. gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
  101. try
  102. {
  103. foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
  104. {
  105. player.CanMove = true;
  106. player.AddShield(GameData.shieldTimeAtBirth);
  107. }
  108. }
  109. finally
  110. {
  111. gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
  112. }
  113. propManager.StartProducing();
  114. new Thread
  115. (
  116. () =>
  117. {
  118. new FrameRateTaskExecutor<int>
  119. (
  120. loopCondition: () => gameMap.Timer.IsGaming,
  121. loopToDo: () =>
  122. {
  123. foreach (var kvp in gameMap.GameObjDict) // 检查物体位置
  124. {
  125. if (kvp.Key == GameObjType.Bullet || kvp.Key == GameObjType.Character || kvp.Key == GameObjType.Prop)
  126. {
  127. gameMap.GameObjLockDict[kvp.Key].EnterWriteLock();
  128. try
  129. {
  130. foreach (var item in gameMap.GameObjDict[kvp.Key])
  131. {
  132. item.Place = gameMap.GetPlaceType(item.Position);
  133. }
  134. }
  135. finally
  136. {
  137. gameMap.GameObjLockDict[kvp.Key].ExitWriteLock();
  138. }
  139. }
  140. }
  141. },
  142. timeInterval: GameData.checkInterval,
  143. finallyReturn: () => 0
  144. )
  145. {
  146. AllowTimeExceed = true
  147. }.Start();
  148. }
  149. )
  150. { IsBackground = true }.Start();
  151. // 开始游戏
  152. if (!gameMap.Timer.StartGame(milliSeconds))
  153. return false;
  154. EndGame(); // 游戏结束时要做的事
  155. return true;
  156. }
  157. public void EndGame()
  158. {
  159. gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
  160. /*try
  161. {
  162. }
  163. finally
  164. {
  165. }*/
  166. gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
  167. }
  168. public void MovePlayer(long playerID, int moveTimeInMilliseconds, double angle)
  169. {
  170. if (!gameMap.Timer.IsGaming)
  171. return;
  172. Character? player = gameMap.FindPlayer(playerID);
  173. if (player != null)
  174. {
  175. actionManager.MovePlayer(player, moveTimeInMilliseconds, angle);
  176. #if DEBUG
  177. Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!");
  178. #endif
  179. }
  180. else
  181. {
  182. #if DEBUG
  183. Console.WriteLine($"PlayerID:{playerID} player does not exists!");
  184. #endif
  185. }
  186. }
  187. public void Attack(long playerID, double angle)
  188. {
  189. if (!gameMap.Timer.IsGaming)
  190. return;
  191. Character? player = gameMap.FindPlayer(playerID);
  192. if (player != null)
  193. {
  194. _ = attackManager.Attack(player, angle);
  195. }
  196. }
  197. public void UseProp(long playerID)
  198. {
  199. if (!gameMap.Timer.IsGaming)
  200. return;
  201. Character? player = gameMap.FindPlayer(playerID);
  202. if (player != null)
  203. {
  204. propManager.UseProp(player);
  205. }
  206. }
  207. public void ThrowProp(long playerID, int timeInmillionSeconds, double angle)
  208. {
  209. if (!gameMap.Timer.IsGaming)
  210. return;
  211. Character? player = gameMap.FindPlayer(playerID);
  212. if (player != null)
  213. {
  214. propManager.ThrowProp(player, timeInmillionSeconds, angle);
  215. }
  216. }
  217. public bool PickProp(long playerID, PropType propType = PropType.Null)
  218. {
  219. if (!gameMap.Timer.IsGaming)
  220. return false;
  221. Character? player = gameMap.FindPlayer(playerID);
  222. if (player != null)
  223. {
  224. return propManager.PickProp(player, propType);
  225. }
  226. return false;
  227. }
  228. public bool UseActiveSkill(long playerID, ActiveSkillType activeSkillType)
  229. {
  230. if (!gameMap.Timer.IsGaming)
  231. return false;
  232. Character? player = gameMap.FindPlayer(playerID);
  233. if (player != null)
  234. {
  235. return skillManager.UseActiveSkill(player, activeSkillType);
  236. }
  237. else
  238. return false;
  239. }
  240. public void AllPlayerUsePassiveSkill()
  241. {
  242. if (!gameMap.Timer.IsGaming)
  243. return;
  244. gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
  245. try
  246. {
  247. foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
  248. {
  249. skillManager.UseAllPassiveSkill(player);
  250. }
  251. }
  252. finally
  253. {
  254. gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
  255. }
  256. }
  257. public void ClearLists(GameObjType[] objIdxes)
  258. {
  259. foreach (var idx in objIdxes)
  260. {
  261. if (idx != GameObjType.Null)
  262. {
  263. gameMap.GameObjLockDict[idx].EnterWriteLock();
  264. try
  265. {
  266. gameMap.GameObjDict[idx].Clear();
  267. }
  268. finally
  269. {
  270. gameMap.GameObjLockDict[idx].ExitWriteLock();
  271. }
  272. }
  273. }
  274. }
  275. public void ClearAllLists()
  276. {
  277. foreach (var keyValuePair in gameMap.GameObjDict)
  278. {
  279. if (((uint)keyValuePair.Key) <= GameData.numOfObjNotMap)
  280. {
  281. gameMap.GameObjLockDict[keyValuePair.Key].EnterWriteLock();
  282. try
  283. {
  284. if (keyValuePair.Key == GameObjType.Character)
  285. {
  286. foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
  287. {
  288. player.CanMove = false;
  289. }
  290. }
  291. gameMap.GameObjDict[keyValuePair.Key].Clear();
  292. }
  293. finally
  294. {
  295. gameMap.GameObjLockDict[keyValuePair.Key].ExitWriteLock();
  296. }
  297. }
  298. }
  299. }
  300. public int GetTeamScore(long teamID)
  301. {
  302. return teamList[(int)teamID].Score;
  303. }
  304. public List<IGameObj> GetGameObj()
  305. {
  306. var gameObjList = new List<IGameObj>();
  307. foreach (var keyValuePair in gameMap.GameObjDict)
  308. {
  309. if (((uint)keyValuePair.Key) <= GameData.numOfObjNotMap)
  310. {
  311. gameMap.GameObjLockDict[keyValuePair.Key].EnterReadLock();
  312. try
  313. {
  314. gameObjList.AddRange(gameMap.GameObjDict[keyValuePair.Key]);
  315. }
  316. finally
  317. {
  318. gameMap.GameObjLockDict[keyValuePair.Key].ExitReadLock();
  319. }
  320. }
  321. }
  322. return gameObjList;
  323. }
  324. public Game(uint[,] mapResource, int numOfTeam)
  325. {
  326. // if (numOfTeam > maxTeamNum) throw new TeamNumOverFlowException();
  327. gameMap = new Map(mapResource);
  328. // 加入队伍
  329. // this.numOfTeam = numOfTeam;
  330. teamList = new List<Team>();
  331. for (int i = 0; i < numOfTeam; ++i)
  332. {
  333. teamList.Add(new Team());
  334. }
  335. skillManager = new SkillManager();
  336. attackManager = new AttackManager(gameMap);
  337. actionManager = new ActionManager(gameMap);
  338. propManager = new PropManager(gameMap);
  339. }
  340. }
  341. }