Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditor / TileView / EditorTileMap.cs
@lijincheng lijincheng on 12 Jul 2023 8 KB 擦除矩形区域
  1. using Godot;
  2. using Godot.Collections;
  3.  
  4. namespace UI.MapEditor;
  5.  
  6. public partial class EditorTileMap : TileMap
  7. {
  8. //鼠标坐标
  9. private Vector2 _mousePosition;
  10. //鼠标所在的cell坐标
  11. private Vector2I _mouseCellPosition;
  12. //上一帧鼠标所在的cell坐标
  13. private Vector2I _prevMouseCellPosition = new Vector2I(-99999, -99999);
  14. //左键开始按下时鼠标所在的坐标
  15. private Vector2I _mouseStartCellPosition;
  16. //鼠标中建是否按下
  17. private bool _isMiddlePressed = false;
  18. private Vector2 _moveOffset;
  19. //左键是否按下
  20. private bool _isLeftPressed = false;
  21. //右键是否按下
  22. private bool _isRightPressed = false;
  23. //绘制填充区域
  24. private bool _drawFullRect = false;
  25.  
  26. public override void _Ready()
  27. {
  28. }
  29.  
  30. public override void _Process(double delta)
  31. {
  32. _drawFullRect = false;
  33. var position = GetLocalMousePosition();
  34. // _mouseCellPosition = new Vector2I(
  35. // Mathf.FloorToInt(position.X / GameConfig.TileCellSize),
  36. // Mathf.FloorToInt(position.Y / GameConfig.TileCellSize)
  37. // );
  38. _mouseCellPosition = LocalToMap(position);
  39. _mousePosition = new Vector2(
  40. _mouseCellPosition.X * GameConfig.TileCellSize,
  41. _mouseCellPosition.Y * GameConfig.TileCellSize
  42. );
  43. //左键绘制
  44. if (_isLeftPressed)
  45. {
  46. if (Input.IsKeyPressed(Key.Shift)) //按住shift绘制矩形
  47. {
  48. _drawFullRect = true;
  49. }
  50. else if (_prevMouseCellPosition != _mouseCellPosition) //鼠标位置变过
  51. {
  52. _prevMouseCellPosition = _mouseCellPosition;
  53. //绘制单个图块
  54. //SetCell(GameConfig.FloorMapLayer, _mouseCellPosition, 0, new Vector2I(0,8));
  55. //绘制自动图块
  56. SetSingleAutoCell(_mouseCellPosition);
  57. }
  58. }
  59. else if (_isRightPressed) //右键擦除
  60. {
  61. if (Input.IsKeyPressed(Key.Shift)) //按住shift擦除矩形
  62. {
  63. _drawFullRect = true;
  64. }
  65. else if (_prevMouseCellPosition != _mouseCellPosition)
  66. {
  67. _prevMouseCellPosition = _mouseCellPosition;
  68. EraseSingleAutoCell(_mouseCellPosition);
  69. }
  70. }
  71. else if (_isMiddlePressed) //中建移动
  72. {
  73. //GD.Print("移动...");
  74. Position = GetGlobalMousePosition() + _moveOffset;
  75. }
  76. }
  77.  
  78. /// <summary>
  79. /// 绘制辅助线
  80. /// </summary>
  81. public void DrawGuides(CanvasItem canvasItem)
  82. {
  83. //轴线
  84. canvasItem.DrawLine(new Vector2(0, 2000), new Vector2(0, -2000), Colors.Green);
  85. canvasItem.DrawLine(new Vector2(2000, 0), new Vector2( -2000, 0), Colors.Red);
  86.  
  87. if (_drawFullRect) //绘制填充矩形
  88. {
  89. var size = TileSet.TileSize;
  90. var cellPos = _mouseStartCellPosition;
  91. var temp = size;
  92. if (_mouseStartCellPosition.X > _mouseCellPosition.X)
  93. {
  94. cellPos.X += 1;
  95. temp.X -= size.X;
  96. }
  97. if (_mouseStartCellPosition.Y > _mouseCellPosition.Y)
  98. {
  99. cellPos.Y += 1;
  100. temp.Y -= size.Y;
  101. }
  102.  
  103. var pos = cellPos * size;
  104. canvasItem.DrawRect(new Rect2(pos, _mousePosition - pos + temp), Colors.Wheat, false);
  105. }
  106. else //绘制单格
  107. {
  108. canvasItem.DrawRect(new Rect2(_mousePosition, TileSet.TileSize), Colors.Wheat, false);
  109. }
  110. }
  111.  
  112. public override void _Input(InputEvent @event)
  113. {
  114. if (@event is InputEventMouseButton mouseButton)
  115. {
  116. if (mouseButton.ButtonIndex == MouseButton.Left) //左键
  117. {
  118. if (mouseButton.Pressed) //按下
  119. {
  120. _mouseStartCellPosition = LocalToMap(GetLocalMousePosition());
  121. }
  122. else
  123. {
  124. if (_drawFullRect) //松开, 提交绘制的矩形区域
  125. {
  126. SetRectAutoCell(_mouseStartCellPosition, _mouseCellPosition);
  127. _drawFullRect = false;
  128. }
  129. }
  130.  
  131. _isLeftPressed = mouseButton.Pressed;
  132. }
  133. else if (mouseButton.ButtonIndex == MouseButton.Right) //右键
  134. {
  135. if (mouseButton.Pressed) //按下
  136. {
  137. _mouseStartCellPosition = LocalToMap(GetLocalMousePosition());
  138. }
  139. else
  140. {
  141. if (_drawFullRect) //松开, 提交擦除的矩形区域
  142. {
  143. EraseRectAutoCell(_mouseStartCellPosition, _mouseCellPosition);
  144. _drawFullRect = false;
  145. }
  146. }
  147. _isRightPressed = mouseButton.Pressed;
  148. }
  149. else if (mouseButton.ButtonIndex == MouseButton.WheelDown)
  150. {
  151. //缩小
  152. Shrink();
  153. }
  154. else if (mouseButton.ButtonIndex == MouseButton.WheelUp)
  155. {
  156. //放大
  157. Magnify();
  158. }
  159. else if (mouseButton.ButtonIndex == MouseButton.Middle)
  160. {
  161. _isMiddlePressed = mouseButton.Pressed;
  162. if (_isMiddlePressed)
  163. {
  164. _moveOffset = Position - mouseButton.GlobalPosition;
  165. }
  166. }
  167. }
  168. }
  169.  
  170. //缩小
  171. private void Shrink()
  172. {
  173. var pos = GetLocalMousePosition();
  174. var scale = Scale / 1.1f;
  175. if (scale.LengthSquared() >= 0.5f)
  176. {
  177. Scale = scale;
  178. Position += pos * 0.1f * scale;
  179. }
  180. else
  181. {
  182. GD.Print("太小了");
  183. }
  184. }
  185. //放大
  186. private void Magnify()
  187. {
  188. var pos = GetLocalMousePosition();
  189. var prevScale = Scale;
  190. var scale = prevScale * 1.1f;
  191. if (scale.LengthSquared() <= 2000)
  192. {
  193. Scale = scale;
  194. Position -= pos * 0.1f * prevScale;
  195. }
  196. else
  197. {
  198. GD.Print("太大了");
  199. }
  200. }
  201.  
  202. //绘制单个自动贴图
  203. private void SetSingleAutoCell(Vector2I position)
  204. {
  205. //绘制自动图块
  206. var arr = new Array<Vector2I>(new [] { position });
  207. SetCellsTerrainConnect(GameConfig.FloorMapLayer, arr, 0, 0, false);
  208. }
  209. //绘制区域自动贴图
  210. private void SetRectAutoCell(Vector2I start, Vector2I end)
  211. {
  212. if (start.X > end.X)
  213. {
  214. var temp = end.X;
  215. end.X = start.X;
  216. start.X = temp;
  217. }
  218. if (start.Y > end.Y)
  219. {
  220. var temp = end.Y;
  221. end.Y = start.Y;
  222. start.Y = temp;
  223. }
  224.  
  225. var x = end.X - start.X + 1;
  226. var y = end.Y - start.Y + 1;
  227. var index = 0;
  228. var array = new Vector2I[x * y];
  229. for (var i = 0; i < x; i++)
  230. {
  231. for (var j = 0; j < y; j++)
  232. {
  233. array[index++] = new Vector2I(start.X + i, start.Y + j);
  234. }
  235. }
  236.  
  237. var arr = new Array<Vector2I>(array);
  238. SetCellsTerrainConnect(GameConfig.FloorMapLayer, arr, 0, 0, false);
  239. }
  240.  
  241. //擦除单个自动图块
  242. private void EraseSingleAutoCell(Vector2I position)
  243. {
  244. EraseCell(GameConfig.FloorMapLayer, position);
  245. }
  246. //擦除一个区域内的自动贴图
  247. private void EraseRectAutoCell(Vector2I start, Vector2I end)
  248. {
  249. if (start.X > end.X)
  250. {
  251. var temp = end.X;
  252. end.X = start.X;
  253. start.X = temp;
  254. }
  255. if (start.Y > end.Y)
  256. {
  257. var temp = end.Y;
  258. end.Y = start.Y;
  259. start.Y = temp;
  260. }
  261.  
  262. var x = end.X - start.X + 1;
  263. var y = end.Y - start.Y + 1;
  264. for (var i = 0; i < x; i++)
  265. {
  266. for (var j = 0; j < y; j++)
  267. {
  268. EraseCell(GameConfig.FloorMapLayer, new Vector2I(start.X + i, start.Y + j));
  269. }
  270. }
  271. }
  272. }