Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / Grid.cs
  1.  
  2. using System.Collections.Generic;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 网格数据结构, 通过 x 和 y 存储数据
  7. /// </summary>
  8. public class Grid<T>
  9. {
  10. /// <summary>
  11. /// 遍历网格数据回调
  12. /// </summary>
  13. public delegate void EachGridCallback(int x, int y, T data);
  14. private readonly Dictionary<int, Dictionary<int, T>> _map = new Dictionary<int, Dictionary<int, T>>();
  15.  
  16. /// <summary>
  17. /// 返回指定xy位置是否存在数据
  18. /// </summary>
  19. public bool Contains(int x, int y)
  20. {
  21. if (_map.TryGetValue(x, out var value))
  22. {
  23. return value.ContainsKey(y);
  24. }
  25.  
  26. return false;
  27. }
  28. /// <summary>
  29. /// 返回指定xy位置是否有数据
  30. /// </summary>
  31. public bool Contains(Vector2I pos)
  32. {
  33. return Contains(pos.X, pos.Y);
  34. }
  35.  
  36. /// <summary>
  37. /// 设置指定xy位置的数据
  38. /// </summary>
  39. public void Set(int x, int y, T data)
  40. {
  41. if (_map.TryGetValue(x, out var value))
  42. {
  43. value[y] = data;
  44. }
  45. else
  46. {
  47. value = new Dictionary<int, T>();
  48. value.Add(y, data);
  49. _map.Add(x, value);
  50. }
  51. }
  52.  
  53. /// <summary>
  54. /// 设置指定坐标的数据
  55. /// </summary>
  56. public void Set(Vector2I pos, T data)
  57. {
  58. Set(pos.X, pos.Y, data);
  59. }
  60.  
  61. /// <summary>
  62. /// 获取指定xy位置的数据
  63. /// </summary>
  64. public T Get(int x, int y)
  65. {
  66. if (_map.TryGetValue(x, out var value))
  67. {
  68. if (value.TryGetValue(y, out var v))
  69. {
  70. return v;
  71. }
  72. }
  73.  
  74. return default;
  75. }
  76.  
  77. /// <summary>
  78. /// 获取指定坐标的数据
  79. /// </summary>
  80. public T Get(Vector2I pos)
  81. {
  82. return Get(pos.X, pos.Y);
  83. }
  84.  
  85. /// <summary>
  86. /// 移除指定xy位置存储的数据
  87. /// </summary>
  88. public bool Remove(int x, int y)
  89. {
  90. if (_map.TryGetValue(x, out var value))
  91. {
  92. return value.Remove(y);
  93. }
  94.  
  95. return false;
  96. }
  97. /// <summary>
  98. /// 往一个区域中填充指定的数据
  99. /// </summary>
  100. /// <param name="pos">起点位置</param>
  101. /// <param name="size">区域大小</param>
  102. /// <param name="data">数据</param>
  103. public void SetRect(Vector2I pos, Vector2I size, T data)
  104. {
  105. var x = pos.X;
  106. var y = pos.Y;
  107. for (var i = 0; i < size.X; i++)
  108. {
  109. for (var j = 0; j < size.Y; j++)
  110. {
  111. if (_map.TryGetValue(x + i, out var value))
  112. {
  113. value[y + j] = data;
  114. }
  115. else
  116. {
  117. value = new Dictionary<int, T>();
  118. value.Add(y + j, data);
  119. _map.Add(x + i, value);
  120. }
  121. }
  122. }
  123. }
  124.  
  125. /// <summary>
  126. /// 移除指定区域数据
  127. /// </summary>
  128. /// <param name="pos">起点位置</param>
  129. /// <param name="size">区域大小</param>
  130. public void RemoveRect(Vector2I pos, Vector2I size)
  131. {
  132. var x = pos.X;
  133. var y = pos.Y;
  134. for (var i = 0; i < size.X; i++)
  135. {
  136. for (var j = 0; j < size.Y; j++)
  137. {
  138. if (_map.TryGetValue(x + i, out var value))
  139. {
  140. value.Remove(y + j);
  141. if (value.Count == 0)
  142. {
  143. _map.Remove(x + i);
  144. }
  145. }
  146. }
  147. }
  148. }
  149.  
  150. /// <summary>
  151. /// 清除所有数据
  152. /// </summary>
  153. public void Clear()
  154. {
  155. _map.Clear();
  156. }
  157. /// <summary>
  158. /// 检测矩形区域内是否与其他数据有碰撞
  159. /// </summary>
  160. /// <param name="pos">起点位置</param>
  161. /// <param name="size">区域大小</param>
  162. public bool RectCollision(Vector2I pos, Vector2I size)
  163. {
  164. var x = pos.X;
  165. var y = pos.Y;
  166. var w = size.X;
  167. var h = size.Y;
  168. //先判断四个角
  169. if (Contains(x, y) || Contains(x + w - 1, y) || Contains(x, y + h - 1) || Contains(x + w - 1, y + h - 1))
  170. {
  171. return true;
  172. }
  173.  
  174. //逐个点判断
  175. for (int i = 1; i < w; i++)
  176. {
  177. for (int j = 0; j < h; j++)
  178. {
  179. if (Contains(x + i, y + j))
  180. {
  181. return true;
  182. }
  183. }
  184. }
  185.  
  186. return false;
  187. }
  188.  
  189. /// <summary>
  190. /// 遍历网格数据
  191. /// </summary>
  192. public void ForEach(EachGridCallback cb)
  193. {
  194. foreach (var pair1 in _map)
  195. {
  196. foreach (var pair2 in pair1.Value)
  197. {
  198. cb(pair1.Key, pair2.Key, pair2.Value);
  199. }
  200. }
  201. }
  202. }