diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorTools.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorTools.tscn index ffdf975..6531b94 100644 --- a/DungeonShooting_Godot/prefab/ui/MapEditorTools.tscn +++ b/DungeonShooting_Godot/prefab/ui/MapEditorTools.tscn @@ -1,11 +1,10 @@ -[gd_scene load_steps=7 format=3 uid="uid://b4u66mxndxbrg"] +[gd_scene load_steps=6 format=3 uid="uid://b4u66mxndxbrg"] [ext_resource type="Script" path="res://src/game/ui/mapEditorTools/MapEditorToolsPanel.cs" id="1_mqp1c"] [ext_resource type="Texture2D" uid="uid://uhhfgdhpk7i4" path="res://icon.png" id="2_rwvbg"] [ext_resource type="Script" path="res://src/game/ui/mapEditorTools/DoorDragArea.cs" id="3_3w0w6"] [ext_resource type="Script" path="res://src/game/ui/mapEditorTools/DoorDragButton.cs" id="3_45muq"] [ext_resource type="Texture2D" uid="uid://4wupcp53rrpi" path="res://resource/sprite/ui/mapEditorTools/DoorDragButton.png" id="3_trbb5"] -[ext_resource type="Texture2D" uid="uid://dcq8xinoyvo85" path="res://resource/sprite/ui/mapEditorTools/DoorDragButton_down.png" id="4_12cej"] [node name="MapEditorTools" type="Control"] layout_mode = 3 @@ -78,8 +77,6 @@ grow_horizontal = 0 grow_vertical = 0 texture_normal = ExtResource("3_trbb5") -texture_pressed = ExtResource("4_12cej") -texture_hover = ExtResource("4_12cej") stretch_mode = 0 script = ExtResource("3_45muq") @@ -93,7 +90,5 @@ offset_right = 66.0 grow_vertical = 0 texture_normal = ExtResource("3_trbb5") -texture_pressed = ExtResource("4_12cej") -texture_hover = ExtResource("4_12cej") stretch_mode = 0 script = ExtResource("3_45muq") diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs index b67d76f..0802f55 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs @@ -11,6 +11,27 @@ public partial class EditorTileMap : TileMap { + + public enum MouseLeftButtonType + { + /// + /// 无状态 + /// + None, + /// + /// 拖拽模式 + /// + Drag, + /// + /// 笔 + /// + Pen, + /// + /// 区域模式 + /// + Area + } + /// /// 自动图块地板层 /// @@ -46,6 +67,8 @@ /// public MapEditorToolsPanel MapEditorToolsPanel { get; set; } + //是否启用绘制图块 + private MouseLeftButtonType _mouseLeftButtonType = MouseLeftButtonType.None; //鼠标坐标 private Vector2 _mousePosition; //鼠标所在的cell坐标 @@ -79,9 +102,8 @@ private Vector2I _checkTerrainErrorPosition = Vector2I.Zero; //是否执行生成地形成功 private bool _isGenerateTerrain = false; - private bool _initLayer = false; - + //--------- 配置数据 ------------- private int _sourceId = 0; private int _terrainSet = 0; @@ -116,7 +138,7 @@ if (!MapEditorToolsPanel.S_HBoxContainer.Instance.IsPositionOver(GetGlobalMousePosition())) //不在Ui节点上 { //左键绘制 - if (_isLeftPressed && false) + if (_isLeftPressed && _mouseLeftButtonType == MouseLeftButtonType.Pen) { if (Input.IsKeyPressed(Key.Shift)) //按住shift绘制矩形 { @@ -130,7 +152,7 @@ SetSingleAutoCell(_mouseCellPosition); } } - else if (_isRightPressed && false) //右键擦除 + else if (_isRightPressed && _mouseLeftButtonType == MouseLeftButtonType.Pen) //右键擦除 { if (Input.IsKeyPressed(Key.Shift)) //按住shift擦除矩形 { @@ -205,28 +227,31 @@ } } - if (_drawFullRect) //绘制填充矩形 + if (_mouseLeftButtonType == MouseLeftButtonType.Pen || _mouseLeftButtonType == MouseLeftButtonType.Area) { - var size = TileSet.TileSize; - var cellPos = _mouseStartCellPosition; - var temp = size; - if (_mouseStartCellPosition.X > _mouseCellPosition.X) + if (_drawFullRect) //绘制填充矩形 { - cellPos.X += 1; - temp.X -= size.X; - } - if (_mouseStartCellPosition.Y > _mouseCellPosition.Y) - { - cellPos.Y += 1; - temp.Y -= size.Y; - } + var size = TileSet.TileSize; + var cellPos = _mouseStartCellPosition; + var temp = size; + if (_mouseStartCellPosition.X > _mouseCellPosition.X) + { + cellPos.X += 1; + temp.X -= size.X; + } + if (_mouseStartCellPosition.Y > _mouseCellPosition.Y) + { + cellPos.Y += 1; + temp.Y -= size.Y; + } - var pos = cellPos * size; - canvasItem.DrawRect(new Rect2(pos, _mousePosition - pos + temp), Colors.White, false, 2f / Scale.X); - } - else //绘制单格 - { - canvasItem.DrawRect(new Rect2(_mousePosition, TileSet.TileSize), Colors.White, false, 2f / Scale.X); + var pos = cellPos * size; + canvasItem.DrawRect(new Rect2(pos, _mousePosition - pos + temp), Colors.White, false, 2f / Scale.X); + } + else //绘制单格 + { + canvasItem.DrawRect(new Rect2(_mousePosition, TileSet.TileSize), Colors.White, false, 2f / Scale.X); + } } } diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorTools/DoorDragArea.cs b/DungeonShooting_Godot/src/game/ui/mapEditorTools/DoorDragArea.cs index 8838d90..c2ac62a 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditorTools/DoorDragArea.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditorTools/DoorDragArea.cs @@ -9,20 +9,34 @@ /// public Vector2 AreaSize => new Vector2(_areaSize, GameConfig.TileCellSize * 2); + //错误时的颜色 + private static Color _errorColor = new Color(1, 0, 0, 0.1882353F); + private MapEditorTools.DoorToolTemplate _node; private Vector2 _startTempPos; private Vector2 _endTempPos; - //区域大小 - private float _areaSize; + //默认颜色 + private Color _defaultColor; + //区域大小, 单位: 像素 + private int _areaSize; + //拖拽松手后是否可以提交 + private bool _canComment = true; + //开始拖拽时的区域 + private Vector2I _startDragRange; public void SetDoorDragAreaNode(MapEditorTools.DoorToolTemplate node) { _node = node; - _areaSize = node.L_DoorArea.Instance.Size.X; + _defaultColor = _node.L_DoorArea.Instance.Color; _node.L_StartBtn.Instance.DragEvent += OnStartAreaDrag; _node.L_EndBtn.Instance.DragEvent += OnEndAreaDrag; + + SetDoorAreaSize(GameConfig.TileCellSize * 4); } + /// + /// 设置位置和缩放, 用于跟随地图 + /// public void SetDoorAreaTransform(Vector2 pos, Vector2 scale) { Position = pos; @@ -30,9 +44,30 @@ } /// + /// 获取门区域所占范围, 单位: 像素, 返回的 Vector2I 的 x 代表起始坐标, y 代表结束坐标 + /// + /// + public Vector2I GetDoorAreaRange() + { + return new Vector2I((int)_node.L_StartBtn.Instance.Position.X, _areaSize); + } + + /// + /// 设置门区域所占范围, + /// + public void SetDoorAreaRange(int start, int size) + { + var startPosition = _node.L_StartBtn.Instance.Position; + startPosition.X = start; + _node.L_StartBtn.Instance.Position = startPosition; + + SetDoorAreaSize(size); + } + + /// /// 设置区域大小 /// - public void SetDoorAreaSize(float value) + public void SetDoorAreaSize(int value) { if (_areaSize != value) { @@ -46,7 +81,7 @@ { var colorRect = _node.L_DoorArea.Instance; var position = colorRect.Position; - position.X = _node.L_StartBtn.Instance.Position.X; + position.X = _node.L_StartBtn.Instance.Position.X + _node.L_StartBtn.Instance.Size.X; colorRect.Position = position; colorRect.Size = AreaSize; @@ -55,20 +90,59 @@ _node.L_EndBtn.Instance.Position = position2; } + //拖拽起始点 private void OnStartAreaDrag(DragState dragState, Vector2 offset) { if (dragState == DragState.DragStart) { + _canComment = true; _startTempPos = _node.L_StartBtn.Instance.Position; + _startDragRange = GetDoorAreaRange(); } else if (dragState == DragState.DragMove) { var position = _startTempPos; position.X = position.X += offset.X; + var endPosition = _node.L_EndBtn.Instance.Position; + + //计算区域大小 + var areaSize = (int)(endPosition.X - position.X - _node.L_StartBtn.Instance.Size.X); + _node.L_StartBtn.Instance.Position = position; - //刷新区域位置 - SetDoorAreaSize(_node.L_EndBtn.Instance.Position.X - position.X); + SetDoorAreaSize(areaSize); + + //起始点坐标必须要小于终点坐标 + if (position.X < endPosition.X) + { + //区域必须大于等于 4 格宽度 + if (areaSize >= GameConfig.TileCellSize * 4) + { + if (!_canComment) + { + _canComment = true; + _node.L_DoorArea.Instance.Color = _defaultColor; + } + return; + } + } + + //错误的位置 + if (_canComment) + { + _canComment = false; + _node.L_DoorArea.Instance.Color = _errorColor; + } + } + else + { + //松手后如果不能提交, 则还原初始位置 + if (!_canComment) + { + _canComment = true; + _node.L_DoorArea.Instance.Color = _defaultColor; + SetDoorAreaRange(_startDragRange.X, _startDragRange.Y); + } } } @@ -76,16 +150,53 @@ { if (dragState == DragState.DragStart) { + _canComment = true; _endTempPos = _node.L_EndBtn.Instance.Position; + _startDragRange = GetDoorAreaRange(); } else if (dragState == DragState.DragMove) { var position = _endTempPos; position.X = position.X += offset.X; - //_node.L_EndBtn.Instance.Position = position; - + + //区域大小 + var areaSize = (int)(position.X - _node.L_StartBtn.Instance.Position.X - _node.L_StartBtn.Instance.Size.X); //刷新区域位置 - SetDoorAreaSize(position.X - _node.L_StartBtn.Instance.Position.X); + SetDoorAreaSize(areaSize); + + //终点坐标必须要大于起始点坐标 + var startPosition = _node.L_StartBtn.Instance.Position; + if (position.X > startPosition.X) + { + + //区域必须大于等于 4 格宽度 + if (areaSize >= GameConfig.TileCellSize * 4) + { + if (!_canComment) + { + _canComment = true; + _node.L_DoorArea.Instance.Color = _defaultColor; + } + return; + } + } + + //错误的位置 + if (_canComment) + { + _canComment = false; + _node.L_DoorArea.Instance.Color = _errorColor; + } + } + else + { + //松手后如果不能提交, 则还原初始位置 + if (!_canComment) + { + _canComment = true; + _node.L_DoorArea.Instance.Color = _defaultColor; + SetDoorAreaRange(_startDragRange.X, _startDragRange.Y); + } } } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorTools/DoorDragButton.cs b/DungeonShooting_Godot/src/game/ui/mapEditorTools/DoorDragButton.cs index 84e18e5..fa65c61 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditorTools/DoorDragButton.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditorTools/DoorDragButton.cs @@ -43,6 +43,7 @@ private void OnButtonDown() { _down = true; + Modulate = new Color(0.7f, 0.7f, 0.7f, 1); _startPos = GetGlobalMousePosition(); _prevPos = Vector2.Zero; if (DragEvent != null) @@ -54,6 +55,7 @@ private void OnButtonUp() { _down = false; + Modulate = new Color(1, 1, 1, 1); if (DragEvent != null) { var offset = Utils.Adsorption((GetGlobalMousePosition() - _startPos) / _parent.Scale, _stepValue);