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 15 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  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 bool Treat(long playerID, long playerTreatedID)
  188. {
  189. if (!gameMap.Timer.IsGaming)
  190. return false;
  191. Character? player = gameMap.FindPlayer(playerID);
  192. Character? playerTreated = gameMap.FindPlayer(playerTreatedID);
  193. if (player != null && playerTreated != null)
  194. {
  195. return actionManager.Treat(player, playerTreated);
  196. }
  197. return false;
  198. }
  199. public bool Rescue(long playerID, long playerRescuedID)
  200. {
  201. if (!gameMap.Timer.IsGaming)
  202. return false;
  203. Character? player = gameMap.FindPlayer(playerID);
  204. Character? playerRescued = gameMap.FindPlayer(playerRescuedID);
  205. if (player != null && playerRescued != null)
  206. {
  207. return actionManager.Treat(player, playerRescued);
  208. }
  209. return false;
  210. }
  211. public bool Fix(long playerID)
  212. {
  213. if (!gameMap.Timer.IsGaming)
  214. return false;
  215. Character? player = gameMap.FindPlayer(playerID);
  216. if (player != null)
  217. {
  218. return actionManager.Fix(player);
  219. }
  220. return false;
  221. }
  222. public bool Escape(long playerID)
  223. {
  224. if (!gameMap.Timer.IsGaming)
  225. return false;
  226. Character? player = gameMap.FindPlayer(playerID);
  227. if (player != null)
  228. {
  229. return actionManager.Escape(player);
  230. }
  231. return false;
  232. }
  233. public void Attack(long playerID, double angle)
  234. {
  235. if (!gameMap.Timer.IsGaming)
  236. return;
  237. Character? player = gameMap.FindPlayer(playerID);
  238. if (player != null)
  239. {
  240. _ = attackManager.Attack(player, angle);
  241. }
  242. }
  243. public void UseProp(long playerID)
  244. {
  245. if (!gameMap.Timer.IsGaming)
  246. return;
  247. Character? player = gameMap.FindPlayer(playerID);
  248. if (player != null)
  249. {
  250. propManager.UseProp(player);
  251. }
  252. }
  253. public void ThrowProp(long playerID, int timeInmillionSeconds, double angle)
  254. {
  255. if (!gameMap.Timer.IsGaming)
  256. return;
  257. Character? player = gameMap.FindPlayer(playerID);
  258. if (player != null)
  259. {
  260. propManager.ThrowProp(player, timeInmillionSeconds, angle);
  261. }
  262. }
  263. public bool PickProp(long playerID, PropType propType = PropType.Null)
  264. {
  265. if (!gameMap.Timer.IsGaming)
  266. return false;
  267. Character? player = gameMap.FindPlayer(playerID);
  268. if (player != null)
  269. {
  270. return propManager.PickProp(player, propType);
  271. }
  272. return false;
  273. }
  274. public bool UseActiveSkill(long playerID, ActiveSkillType activeSkillType)
  275. {
  276. if (!gameMap.Timer.IsGaming)
  277. return false;
  278. Character? player = gameMap.FindPlayer(playerID);
  279. if (player != null)
  280. {
  281. return skillManager.UseActiveSkill(player, activeSkillType);
  282. }
  283. else
  284. return false;
  285. }
  286. public void AllPlayerUsePassiveSkill()
  287. {
  288. if (!gameMap.Timer.IsGaming)
  289. return;
  290. gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
  291. try
  292. {
  293. foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
  294. {
  295. skillManager.UseAllPassiveSkill(player);
  296. }
  297. }
  298. finally
  299. {
  300. gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
  301. }
  302. }
  303. public void ClearLists(GameObjType[] objIdxes)
  304. {
  305. foreach (var idx in objIdxes)
  306. {
  307. if (idx != GameObjType.Null)
  308. {
  309. gameMap.GameObjLockDict[idx].EnterWriteLock();
  310. try
  311. {
  312. gameMap.GameObjDict[idx].Clear();
  313. }
  314. finally
  315. {
  316. gameMap.GameObjLockDict[idx].ExitWriteLock();
  317. }
  318. }
  319. }
  320. }
  321. public void ClearAllLists()
  322. {
  323. foreach (var keyValuePair in gameMap.GameObjDict)
  324. {
  325. if (((uint)keyValuePair.Key) <= GameData.numOfObjNotMap)
  326. {
  327. gameMap.GameObjLockDict[keyValuePair.Key].EnterWriteLock();
  328. try
  329. {
  330. if (keyValuePair.Key == GameObjType.Character)
  331. {
  332. foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
  333. {
  334. player.CanMove = false;
  335. }
  336. }
  337. gameMap.GameObjDict[keyValuePair.Key].Clear();
  338. }
  339. finally
  340. {
  341. gameMap.GameObjLockDict[keyValuePair.Key].ExitWriteLock();
  342. }
  343. }
  344. }
  345. }
  346. public int GetTeamScore(long teamID)
  347. {
  348. return teamList[(int)teamID].Score;
  349. }
  350. public List<IGameObj> GetGameObj()
  351. {
  352. var gameObjList = new List<IGameObj>();
  353. foreach (var keyValuePair in gameMap.GameObjDict)
  354. {
  355. if (((uint)keyValuePair.Key) <= GameData.numOfObjNotMap)
  356. {
  357. gameMap.GameObjLockDict[keyValuePair.Key].EnterReadLock();
  358. try
  359. {
  360. gameObjList.AddRange(gameMap.GameObjDict[keyValuePair.Key]);
  361. }
  362. finally
  363. {
  364. gameMap.GameObjLockDict[keyValuePair.Key].ExitReadLock();
  365. }
  366. }
  367. }
  368. return gameObjList;
  369. }
  370. public Game(uint[,] mapResource, int numOfTeam)
  371. {
  372. // if (numOfTeam > maxTeamNum) throw new TeamNumOverFlowException();
  373. gameMap = new Map(mapResource);
  374. // 加入队伍
  375. // this.numOfTeam = numOfTeam;
  376. teamList = new List<Team>();
  377. for (int i = 0; i < numOfTeam; ++i)
  378. {
  379. teamList.Add(new Team());
  380. }
  381. skillManager = new SkillManager();
  382. attackManager = new AttackManager(gameMap);
  383. actionManager = new ActionManager(gameMap);
  384. propManager = new PropManager(gameMap);
  385. }
  386. }
  387. }