diff --git a/DungeonShooting_Godot/prefab/ui/MapEditor.tscn b/DungeonShooting_Godot/prefab/ui/MapEditor.tscn index 3933a05..7630a77 100644 --- a/DungeonShooting_Godot/prefab/ui/MapEditor.tscn +++ b/DungeonShooting_Godot/prefab/ui/MapEditor.tscn @@ -53,6 +53,9 @@ format = 2 script = ExtResource("2_waq8f") +[node name="Draw" type="Node2D" parent="Bg/HSplitContainer/Left/MapView/SubViewport/TileMap"] +z_index = 100 + [node name="Right" type="Panel" parent="Bg/HSplitContainer"] custom_minimum_size = Vector2(300, 0) layout_mode = 2 diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/MapEditor.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/MapEditor.cs index 8e2dc67..92d735e 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/MapEditor.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/MapEditor.cs @@ -24,10 +24,32 @@ } /// + /// 类型: , 路径: MapEditor.Bg.HSplitContainer.Left.MapView.SubViewport.TileMap.Draw + /// + public class MapEditor_Draw : IUiNode + { + public MapEditor_Draw(Godot.Node2D node) : base(node) { } + public override MapEditor_Draw Clone() => new ((Godot.Node2D)Instance.Duplicate()); + } + + /// /// 类型: , 路径: MapEditor.Bg.HSplitContainer.Left.MapView.SubViewport.TileMap /// public class MapEditor_TileMap : IUiNode { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditor.Bg.HSplitContainer.Left.MapView.SubViewport.Draw + /// + public MapEditor_Draw L_Draw + { + get + { + if (_L_Draw == null) _L_Draw = new MapEditor_Draw(Instance.GetNodeOrNull("Draw")); + return _L_Draw; + } + } + private MapEditor_Draw _L_Draw; + public MapEditor_TileMap(UI.MapEditor.EditorTileMap node) : base(node) { } public override MapEditor_TileMap Clone() => new ((UI.MapEditor.EditorTileMap)Instance.Duplicate()); } @@ -166,6 +188,11 @@ /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditor.Bg.HSplitContainer.Left.MapView.SubViewport.TileMap.Draw + /// + public MapEditor_Draw S_Draw => L_Bg.L_HSplitContainer.L_Left.L_MapView.L_SubViewport.L_TileMap.L_Draw; + + /// /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditor.Bg.HSplitContainer.Left.MapView.SubViewport.TileMap /// public MapEditor_TileMap S_TileMap => L_Bg.L_HSplitContainer.L_Left.L_MapView.L_SubViewport.L_TileMap; diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs index 8aa2366..ff83da3 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs @@ -1,4 +1,5 @@ using Godot; +using Godot.Collections; namespace UI.MapEditor; @@ -10,32 +11,54 @@ private Vector2I _mouseCellPosition; //上一帧鼠标所在的cell坐标 private Vector2I _prevMouseCellPosition = new Vector2I(-99999, -99999); + //左键开始按下时鼠标所在的坐标 + private Vector2I _mouseStartCellPosition; //鼠标中建是否按下 private bool _isMiddlePressed = false; private Vector2 _moveOffset; + //左键是否按下 + private bool _isLeftPressed = false; + //右键是否按下 + private bool _isRightPressed = false; + //绘制填充区域 + private bool _drawFullRect = false; + + public override void _Ready() + { + + } public override void _Process(double delta) { + _drawFullRect = false; var position = GetLocalMousePosition(); - _mouseCellPosition = new Vector2I( - Mathf.FloorToInt(position.X / GameConfig.TileCellSize), - Mathf.FloorToInt(position.Y / GameConfig.TileCellSize) - ); + // _mouseCellPosition = new Vector2I( + // Mathf.FloorToInt(position.X / GameConfig.TileCellSize), + // Mathf.FloorToInt(position.Y / GameConfig.TileCellSize) + // ); + _mouseCellPosition = LocalToMap(position); _mousePosition = new Vector2( _mouseCellPosition.X * GameConfig.TileCellSize, _mouseCellPosition.Y * GameConfig.TileCellSize ); - + //左键绘制 - if (Input.IsMouseButtonPressed(MouseButton.Left)) + if (_isLeftPressed) { - if (_prevMouseCellPosition != _mouseCellPosition) + if (Input.IsKeyPressed(Key.Shift)) //按住shift绘制矩形 + { + _drawFullRect = true; + } + else if (_prevMouseCellPosition != _mouseCellPosition) //鼠标位置变过 { _prevMouseCellPosition = _mouseCellPosition; - SetCell(GameConfig.FloorMapLayer, _mouseCellPosition, 0, new Vector2I(0,8)); + //绘制单个图块 + //SetCell(GameConfig.FloorMapLayer, _mouseCellPosition, 0, new Vector2I(0,8)); + //绘制自动图块 + SetSingleAutoCell(_mouseCellPosition); } } - else if (Input.IsMouseButtonPressed(MouseButton.Right)) //右键擦除 + else if (_isRightPressed) //右键擦除 { if (_prevMouseCellPosition != _mouseCellPosition) { @@ -50,18 +73,66 @@ } } - public override void _Draw() + /// + /// 绘制辅助线 + /// + public void DrawGuides(CanvasItem canvasItem) { - DrawRect(new Rect2(_mousePosition, GameConfig.TileCellSize, GameConfig.TileCellSize), Colors.Wheat, false); - DrawLine(new Vector2(0, 2000), new Vector2(0, -2000), Colors.Green); - DrawLine(new Vector2(2000, 0), new Vector2( -2000, 0), Colors.Red); + //轴线 + canvasItem.DrawLine(new Vector2(0, 2000), new Vector2(0, -2000), Colors.Green); + canvasItem.DrawLine(new Vector2(2000, 0), new Vector2( -2000, 0), Colors.Red); + + if (_drawFullRect) //绘制填充矩形 + { + 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.Wheat, false); + } + else + { + canvasItem.DrawRect(new Rect2(_mousePosition, TileSet.TileSize), Colors.Wheat, false); + } } public override void _Input(InputEvent @event) { if (@event is InputEventMouseButton mouseButton) { - if (mouseButton.ButtonIndex == MouseButton.WheelDown) + if (mouseButton.ButtonIndex == MouseButton.Left) //左键 + { + if (mouseButton.Pressed) //按下 + { + _mouseStartCellPosition = LocalToMap(GetLocalMousePosition()); + } + else + { + if (_drawFullRect) //松开, 提交绘制的矩形区域 + { + SetRectAutoCell(_mouseStartCellPosition, _mouseCellPosition); + _drawFullRect = false; + } + } + + _isLeftPressed = mouseButton.Pressed; + } + else if (mouseButton.ButtonIndex == MouseButton.Right) //右键 + { + _isRightPressed = mouseButton.Pressed; + } + else if (mouseButton.ButtonIndex == MouseButton.WheelDown) { //缩小 Shrink(); @@ -114,4 +185,47 @@ GD.Print("太大了"); } } + + //绘制单个自动贴图 + private void SetSingleAutoCell(Vector2I position) + { + //绘制自动图块 + var arr = new Array(new [] + { + position + }); + SetCellsTerrainConnect(GameConfig.FloorMapLayer, arr, 0, 0, false); + } + + //绘制区域自动贴图 + private void SetRectAutoCell(Vector2I start, Vector2I end) + { + if (start.X > end.X) + { + var temp = end.X; + end.X = start.X; + start.X = temp; + } + if (start.Y > end.Y) + { + var temp = end.Y; + end.Y = start.Y; + start.Y = temp; + } + + var x = end.X - start.X + 1; + var y = end.Y - start.Y + 1; + var index = 0; + var array = new Vector2I[x * y]; + for (var i = 0; i < x; i++) + { + for (var j = 0; j < y; j++) + { + array[index++] = new Vector2I(start.X + i, start.Y + j); + } + } + + var arr = new Array(array); + SetCellsTerrainConnect(GameConfig.FloorMapLayer, arr, 0, 0, false); + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMapBar.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMapBar.cs index 5125952..5b31cdd 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMapBar.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMapBar.cs @@ -11,18 +11,21 @@ public void OnShow() { - + _editorTileMap.L_Draw.Instance.Draw += OnDrawGuides; } public void OnHide() { - + _editorTileMap.L_Draw.Instance.Draw -= OnDrawGuides; } public void Process(float delta) { - _editorTileMap.Instance.QueueRedraw(); + _editorTileMap.L_Draw.Instance.QueueRedraw(); } - - + + private void OnDrawGuides() + { + _editorTileMap.Instance.DrawGuides(_editorTileMap.L_Draw.Instance); + } } \ No newline at end of file