diff --git a/DungeonShooting_Godot/prefab/ui/EditorForm.tscn b/DungeonShooting_Godot/prefab/ui/EditorForm.tscn
new file mode 100644
index 0000000..295dd77
--- /dev/null
+++ b/DungeonShooting_Godot/prefab/ui/EditorForm.tscn
@@ -0,0 +1,41 @@
+[gd_scene load_steps=2 format=3 uid="uid://djfbqfqkjoquj"]
+
+[ext_resource type="Script" path="res://src/game/ui/editorForm/EditorFormPanel.cs" id="1_oq0ff"]
+
+[node name="EditorForm" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+script = ExtResource("1_oq0ff")
+
+[node name="MarginContainer" type="MarginContainer" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 20
+theme_override_constants/margin_top = 50
+theme_override_constants/margin_right = 20
+theme_override_constants/margin_bottom = 20
+
+[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
+layout_mode = 2
+
+[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/separation = 20
+
+[node name="Item" type="HBoxContainer" parent="MarginContainer/ScrollContainer/VBoxContainer"]
+layout_mode = 2
+
+[node name="NameLabel" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer/Item"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_stretch_ratio = 20.0
+text = "名称:"
+horizontal_alignment = 2
+vertical_alignment = 1
diff --git a/DungeonShooting_Godot/resource/map/tileSet/TileSet2/TileSet.json b/DungeonShooting_Godot/resource/map/tileSet/TileSet2/TileSet.json
index e4ac01c..4a8fc8a 100644
--- a/DungeonShooting_Godot/resource/map/tileSet/TileSet2/TileSet.json
+++ b/DungeonShooting_Godot/resource/map/tileSet/TileSet2/TileSet.json
@@ -94,6 +94,54 @@
]
},
"TerrainType": 0
+ },
+ {
+ "Name": "Test",
+ "F": {},
+ "M": {},
+ "T": {
+ "16": [
+ 0,
+ 128
+ ],
+ "48": [
+ 16,
+ 128
+ ],
+ "56": [
+ 32,
+ 128
+ ]
+ },
+ "TerrainType": 0
+ },
+ {
+ "Name": "Test2",
+ "F": {},
+ "M": {},
+ "T": {
+ "341": [
+ 176,
+ 48
+ ],
+ "80": [
+ 48,
+ 32
+ ],
+ "272": [
+ 16,
+ 32
+ ],
+ "336": [
+ 32,
+ 32
+ ],
+ "276": [
+ 16,
+ 48
+ ]
+ },
+ "TerrainType": 1
}
],
"Combination": [
diff --git a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs
index bb13117..2e3fb0d 100644
--- a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs
+++ b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs
@@ -52,10 +52,11 @@
{
var uiCell = _cellList[newIndex];
uiCell.OnSelect();
- if (SelectEvent != null)
- {
- SelectEvent(newIndex);
- }
+ }
+
+ if (SelectEvent != null)
+ {
+ SelectEvent(newIndex);
}
}
}
@@ -343,15 +344,17 @@
}
///
- /// 添加单条 Cell 数据
+ /// 添加单条 Cell 数据, select 为是否立即选中
///
- public void Add(TData data)
+ public void Add(TData data, bool select = false)
{
- //取消选中
- SelectIndex = -1;
var cell = GetCellInstance();
GridContainer.AddChild(cell.CellNode.GetUiInstance());
cell.SetData(data);
+ if (select)
+ {
+ SelectIndex = Count - 1;
+ }
}
///
diff --git a/DungeonShooting_Godot/src/game/data/FormItemData.cs b/DungeonShooting_Godot/src/game/data/FormItemData.cs
new file mode 100644
index 0000000..f6fa43e
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/data/FormItemData.cs
@@ -0,0 +1,20 @@
+
+using Godot;
+
+public class FormItemData where T : Control
+{
+ ///
+ /// 显示文本
+ ///
+ public string Label;
+ ///
+ /// 挂载的节点
+ ///
+ public T UiNode;
+
+ public FormItemData(string label, T uiNode)
+ {
+ Label = label;
+ UiNode = uiNode;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/manager/EditorWindowManager.cs b/DungeonShooting_Godot/src/game/manager/EditorWindowManager.cs
index 0b9e948..de043ba 100644
--- a/DungeonShooting_Godot/src/game/manager/EditorWindowManager.cs
+++ b/DungeonShooting_Godot/src/game/manager/EditorWindowManager.cs
@@ -5,6 +5,7 @@
using Config;
using Godot;
using UI.EditorColorPicker;
+using UI.EditorForm;
using UI.EditorImportCombination;
using UI.EditorInfo;
using UI.EditorInput;
@@ -226,7 +227,7 @@
//检查名称是否合规
if (string.IsNullOrEmpty(groupName))
{
- ShowTips("错误", "组名称不能为空!");
+ ShowTips("错误", "组名称不能为空!");
return;
}
@@ -235,7 +236,7 @@
var dir = new DirectoryInfo(path);
if (dir.Exists && dir.GetDirectories().Length > 0)
{
- ShowTips("错误", $"已经有相同路径的房间了!");
+ ShowTips("错误", $"已经有相同路径的房间了!");
return;
}
@@ -586,7 +587,7 @@
//检查名称是否合规
if (string.IsNullOrEmpty(name))
{
- ShowTips("错误", "名称不能为空!");
+ ShowTips("错误", "名称不能为空!");
return;
}
@@ -595,7 +596,7 @@
var dir = new DirectoryInfo(path);
if (dir.Exists && dir.GetFiles().Length > 0)
{
- ShowTips("错误", $"已经有相同名称的TileSet了!");
+ ShowTips("错误", $"已经有相同名称的TileSet了!");
return;
}
@@ -641,6 +642,116 @@
})
);
}
+
+ ///
+ /// 显示创建地形的面板
+ ///
+ /// 创建地形时所在的TileSource
+ /// 创建完成回调
+ /// 所属父级Ui
+ public static void ShowCreateTerrain(TileSetSourceInfo sourceInfo, Action onCreate, UiBase parentUi = null)
+ {
+ var window = CreateWindowInstance(parentUi);
+ window.SetWindowTitle("创建Terrain");
+ window.SetWindowSize(new Vector2I(600, 350));
+ var body = window.OpenBody(UiManager.UiNames.EditorForm);
+
+ //第一项
+ var item1 = new FormItemData("地形名称", new LineEdit()
+ {
+ PlaceholderText = "请输入名称"
+ });
+ //第二项
+ var option = new OptionButton();
+ option.AddItem("3x3掩码(47格)");
+ option.AddItem("2x2掩码(13格)");
+ option.Selected = 0;
+ var item2 = new FormItemData("掩码类型", option);
+
+ body.AddItem(item1);
+ body.AddItem(item2);
+ window.SetButtonList(
+ new EditorWindowPanel.ButtonData("确定", () =>
+ {
+ var text = item1.UiNode.Text;
+ if (string.IsNullOrEmpty(text))
+ {
+ ShowTips("错误", $"名称不允许为空!");
+ return;
+ }
+
+ if (sourceInfo.Terrain.FindIndex(info => info.Name == text) >= 0)
+ {
+ ShowTips("错误", $"已经有相同名称的Terrain了!");
+ return;
+ }
+
+ var terrainInfo = new TileSetTerrainInfo();
+ terrainInfo.InitData();
+ terrainInfo.Name = text;
+ terrainInfo.TerrainType = (byte)option.Selected;
+
+ window.CloseWindow();
+ onCreate(terrainInfo);
+ }),
+ new EditorWindowPanel.ButtonData("取消", () =>
+ {
+ window.CloseWindow();
+ })
+ );
+ }
+
+ ///
+ /// 显示编辑地形的MainBu
+ ///
+ /// 创建地形时所在的TileSource
+ /// 创建完成回调
+ /// 所属父级Ui
+ public static void ShowEditTerrain(TileSetSourceInfo sourceInfo, Action onCreate, UiBase parentUi = null)
+ {
+ var window = CreateWindowInstance(parentUi);
+ window.SetWindowTitle("创建Terrain");
+ window.SetWindowSize(new Vector2I(600, 350));
+ var body = window.OpenBody(UiManager.UiNames.EditorForm);
+
+ //第一项
+ var item1 = new FormItemData("地形名称", new LineEdit()
+ {
+ PlaceholderText = "请输入名称"
+ });
+ //第二项
+ var option = new OptionButton();
+ option.AddItem("3x3掩码(47格)");
+ option.AddItem("2x2掩码(13格)");
+ option.Selected = 0;
+ var item2 = new FormItemData("掩码类型", option);
+
+ body.AddItem(item1);
+ body.AddItem(item2);
+ window.SetButtonList(
+ new EditorWindowPanel.ButtonData("确定", () =>
+ {
+ var text = item1.UiNode.Text;
+ if (sourceInfo.Terrain.FindIndex(info => info.Name == text) >= 0)
+ {
+ ShowTips("错误", $"已经有相同名称的Terrain了!");
+ return;
+ }
+
+ var terrainInfo = new TileSetTerrainInfo();
+ terrainInfo.InitData();
+ terrainInfo.Name = text;
+ terrainInfo.TerrainType = (byte)option.Selected;
+
+ window.CloseWindow();
+ onCreate(terrainInfo);
+ }),
+ new EditorWindowPanel.ButtonData("取消", () =>
+ {
+ window.CloseWindow();
+ })
+ );
+ }
private static EditorWindowPanel CreateWindowInstance(UiBase parentUi = null)
{
diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
index 0e3e43f..f361dc8 100644
--- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
+++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
@@ -70,7 +70,9 @@
public const string prefab_ui_BottomTips_tscn = "res://prefab/ui/BottomTips.tscn";
public const string prefab_ui_Debugger_tscn = "res://prefab/ui/Debugger.tscn";
public const string prefab_ui_EditorColorPicker_tscn = "res://prefab/ui/EditorColorPicker.tscn";
+ public const string prefab_ui_EditorForm_tscn = "res://prefab/ui/EditorForm.tscn";
public const string prefab_ui_EditorImportCombination_tscn = "res://prefab/ui/EditorImportCombination.tscn";
+ public const string prefab_ui_EditorInfo_tscn = "res://prefab/ui/EditorInfo.tscn";
public const string prefab_ui_EditorInput_tscn = "res://prefab/ui/EditorInput.tscn";
public const string prefab_ui_EditorTips_tscn = "res://prefab/ui/EditorTips.tscn";
public const string prefab_ui_EditorTools_tscn = "res://prefab/ui/EditorTools.tscn";
@@ -78,7 +80,6 @@
public const string prefab_ui_Loading_tscn = "res://prefab/ui/Loading.tscn";
public const string prefab_ui_Main_tscn = "res://prefab/ui/Main.tscn";
public const string prefab_ui_MapEditor_tscn = "res://prefab/ui/MapEditor.tscn";
- public const string prefab_ui_MapEditorCreateGroup_tscn = "res://prefab/ui/MapEditorCreateGroup.tscn";
public const string prefab_ui_MapEditorCreateMark_tscn = "res://prefab/ui/MapEditorCreateMark.tscn";
public const string prefab_ui_MapEditorCreatePreinstall_tscn = "res://prefab/ui/MapEditorCreatePreinstall.tscn";
public const string prefab_ui_MapEditorCreateRoom_tscn = "res://prefab/ui/MapEditorCreateRoom.tscn";
@@ -121,6 +122,12 @@
public const string resource_font_DinkieBitmap9pxItalicDemo_ttf = "res://resource/font/DinkieBitmap-9pxItalicDemo.ttf";
public const string resource_font_VonwaonBitmap12px_ttf = "res://resource/font/VonwaonBitmap-12px.ttf";
public const string resource_font_VonwaonBitmap16px_ttf = "res://resource/font/VonwaonBitmap-16px.ttf";
+ public const string resource_map_tileSet_TileSetConfig_json = "res://resource/map/tileSet/TileSetConfig.json";
+ public const string resource_map_tileSet_TileSet1_Main_png = "res://resource/map/tileSet/TileSet1/Main.png";
+ public const string resource_map_tileSet_TileSet1_TileSet_json = "res://resource/map/tileSet/TileSet1/TileSet.json";
+ public const string resource_map_tileSet_TileSet2_Main_png = "res://resource/map/tileSet/TileSet2/Main.png";
+ public const string resource_map_tileSet_TileSet2_Test2_png = "res://resource/map/tileSet/TileSet2/Test2.png";
+ public const string resource_map_tileSet_TileSet2_TileSet_json = "res://resource/map/tileSet/TileSet2/TileSet.json";
public const string resource_material_Blend_gdshader = "res://resource/material/Blend.gdshader";
public const string resource_material_Blend_tres = "res://resource/material/Blend.tres";
public const string resource_material_GodRays_gdshader = "res://resource/material/GodRays.gdshader";
@@ -228,6 +235,7 @@
public const string resource_sprite_map_TerrainMask_png = "res://resource/sprite/map/TerrainMask.png";
public const string resource_sprite_map_TerrainMask2_png = "res://resource/sprite/map/TerrainMask2.png";
public const string resource_sprite_map_TerrainMask3_png = "res://resource/sprite/map/TerrainMask3.png";
+ public const string resource_sprite_map_TerrainMask4_png = "res://resource/sprite/map/TerrainMask4.png";
public const string resource_sprite_map_WallTransition1_png = "res://resource/sprite/map/WallTransition1.png";
public const string resource_sprite_map_WallTransition2_png = "res://resource/sprite/map/WallTransition2.png";
public const string resource_sprite_map_WallTransition3_png = "res://resource/sprite/map/WallTransition3.png";
@@ -332,6 +340,7 @@
public const string resource_sprite_ui_commonIcon_Select_png = "res://resource/sprite/ui/commonIcon/Select.png";
public const string resource_sprite_ui_commonIcon_Select2_png = "res://resource/sprite/ui/commonIcon/Select2.png";
public const string resource_sprite_ui_commonIcon_Setting_png = "res://resource/sprite/ui/commonIcon/Setting.png";
+ public const string resource_sprite_ui_commonIcon_Success_mini_png = "res://resource/sprite/ui/commonIcon/Success_mini.png";
public const string resource_sprite_ui_commonIcon_Unknown_png = "res://resource/sprite/ui/commonIcon/Unknown.png";
public const string resource_sprite_ui_commonIcon_UnknownActivity_png = "res://resource/sprite/ui/commonIcon/UnknownActivity.png";
public const string resource_sprite_ui_commonIcon_Unlock_png = "res://resource/sprite/ui/commonIcon/Unlock.png";
@@ -444,6 +453,7 @@
public const string scene_test_TestCreateSector_tscn = "res://scene/test/TestCreateSector.tscn";
public const string scene_test_TestDrawSprite_tscn = "res://scene/test/TestDrawSprite.tscn";
public const string scene_test_TestGridData_tscn = "res://scene/test/TestGridData.tscn";
+ public const string scene_test_TestLoadTileSetConfig_tscn = "res://scene/test/TestLoadTileSetConfig.tscn";
public const string scene_test_TestMask_tscn = "res://scene/test/TestMask.tscn";
public const string scene_test_TestMask2_tscn = "res://scene/test/TestMask2.tscn";
public const string scene_test_TestNavigation2_tscn = "res://scene/test/TestNavigation2.tscn";
@@ -455,5 +465,6 @@
public const string scene_test_TestPerfectPixel_tscn = "res://scene/test/TestPerfectPixel.tscn";
public const string scene_test_TestPerfectPixelScene_tscn = "res://scene/test/TestPerfectPixelScene.tscn";
public const string scene_test_TestRoomFog_tscn = "res://scene/test/TestRoomFog.tscn";
+ public const string scene_test_TestTerrain2x2_tscn = "res://scene/test/TestTerrain2x2.tscn";
public const string scene_test_TestTileLayer_tscn = "res://scene/test/TestTileLayer.tscn";
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs
index cd4187a..3f4a528 100644
--- a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs
+++ b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs
@@ -8,6 +8,7 @@
public const string BottomTips = "BottomTips";
public const string Debugger = "Debugger";
public const string EditorColorPicker = "EditorColorPicker";
+ public const string EditorForm = "EditorForm";
public const string EditorImportCombination = "EditorImportCombination";
public const string EditorInfo = "EditorInfo";
public const string EditorInput = "EditorInput";
@@ -182,6 +183,54 @@
}
///
+ /// 创建 EditorForm, 并返回UI实例, 该函数不会打开 Ui
+ ///
+ public static UI.EditorForm.EditorFormPanel Create_EditorForm()
+ {
+ return CreateUi(UiNames.EditorForm);
+ }
+
+ ///
+ /// 打开 EditorForm, 并返回UI实例
+ ///
+ public static UI.EditorForm.EditorFormPanel Open_EditorForm()
+ {
+ return OpenUi(UiNames.EditorForm);
+ }
+
+ ///
+ /// 隐藏 EditorForm 的所有实例
+ ///
+ public static void Hide_EditorForm()
+ {
+ var uiInstance = Get_EditorForm_Instance();
+ foreach (var uiPanel in uiInstance)
+ {
+ uiPanel.HideUi();
+ }
+ }
+
+ ///
+ /// 销毁 EditorForm 的所有实例
+ ///
+ public static void Destroy_EditorForm()
+ {
+ var uiInstance = Get_EditorForm_Instance();
+ foreach (var uiPanel in uiInstance)
+ {
+ uiPanel.Destroy();
+ }
+ }
+
+ ///
+ /// 获取所有 EditorForm 的实例, 如果没有实例, 则返回一个空数组
+ ///
+ public static UI.EditorForm.EditorFormPanel[] Get_EditorForm_Instance()
+ {
+ return GetUiInstance(nameof(UI.EditorForm.EditorForm));
+ }
+
+ ///
/// 创建 EditorImportCombination, 并返回UI实例, 该函数不会打开 Ui
///
public static UI.EditorImportCombination.EditorImportCombinationPanel Create_EditorImportCombination()
diff --git a/DungeonShooting_Godot/src/game/ui/editorForm/EditorForm.cs b/DungeonShooting_Godot/src/game/ui/editorForm/EditorForm.cs
new file mode 100644
index 0000000..59f6b34
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/ui/editorForm/EditorForm.cs
@@ -0,0 +1,154 @@
+namespace UI.EditorForm;
+
+///
+/// Ui代码, 该类是根据ui场景自动生成的, 请不要手动编辑该类, 以免造成代码丢失
+///
+public abstract partial class EditorForm : UiBase
+{
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: EditorForm.MarginContainer
+ ///
+ public MarginContainer L_MarginContainer
+ {
+ get
+ {
+ if (_L_MarginContainer == null) _L_MarginContainer = new MarginContainer((EditorFormPanel)this, GetNode("MarginContainer"));
+ return _L_MarginContainer;
+ }
+ }
+ private MarginContainer _L_MarginContainer;
+
+
+ public EditorForm() : base(nameof(EditorForm))
+ {
+ }
+
+ public sealed override void OnInitNestedUi()
+ {
+
+ }
+
+ ///
+ /// 类型: , 路径: EditorForm.MarginContainer.ScrollContainer.VBoxContainer.Item.NameLabel
+ ///
+ public class NameLabel : UiNode
+ {
+ public NameLabel(EditorFormPanel uiPanel, Godot.Label node) : base(uiPanel, node) { }
+ public override NameLabel Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: EditorForm.MarginContainer.ScrollContainer.VBoxContainer.Item
+ ///
+ public class Item : UiNode
+ {
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: EditorForm.MarginContainer.ScrollContainer.VBoxContainer.NameLabel
+ ///
+ public NameLabel L_NameLabel
+ {
+ get
+ {
+ if (_L_NameLabel == null) _L_NameLabel = new NameLabel(UiPanel, Instance.GetNode("NameLabel"));
+ return _L_NameLabel;
+ }
+ }
+ private NameLabel _L_NameLabel;
+
+ public Item(EditorFormPanel uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { }
+ public override Item Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: EditorForm.MarginContainer.ScrollContainer.VBoxContainer
+ ///
+ public class VBoxContainer : UiNode
+ {
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: EditorForm.MarginContainer.ScrollContainer.Item
+ ///
+ public Item L_Item
+ {
+ get
+ {
+ if (_L_Item == null) _L_Item = new Item(UiPanel, Instance.GetNode("Item"));
+ return _L_Item;
+ }
+ }
+ private Item _L_Item;
+
+ public VBoxContainer(EditorFormPanel uiPanel, Godot.VBoxContainer node) : base(uiPanel, node) { }
+ public override VBoxContainer Clone() => new (UiPanel, (Godot.VBoxContainer)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: EditorForm.MarginContainer.ScrollContainer
+ ///
+ public class ScrollContainer : UiNode
+ {
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: EditorForm.MarginContainer.VBoxContainer
+ ///
+ public VBoxContainer L_VBoxContainer
+ {
+ get
+ {
+ if (_L_VBoxContainer == null) _L_VBoxContainer = new VBoxContainer(UiPanel, Instance.GetNode("VBoxContainer"));
+ return _L_VBoxContainer;
+ }
+ }
+ private VBoxContainer _L_VBoxContainer;
+
+ public ScrollContainer(EditorFormPanel uiPanel, Godot.ScrollContainer node) : base(uiPanel, node) { }
+ public override ScrollContainer Clone() => new (UiPanel, (Godot.ScrollContainer)Instance.Duplicate());
+ }
+
+ ///
+ /// 类型: , 路径: EditorForm.MarginContainer
+ ///
+ public class MarginContainer : UiNode
+ {
+ ///
+ /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: EditorForm.ScrollContainer
+ ///
+ public ScrollContainer L_ScrollContainer
+ {
+ get
+ {
+ if (_L_ScrollContainer == null) _L_ScrollContainer = new ScrollContainer(UiPanel, Instance.GetNode("ScrollContainer"));
+ return _L_ScrollContainer;
+ }
+ }
+ private ScrollContainer _L_ScrollContainer;
+
+ public MarginContainer(EditorFormPanel uiPanel, Godot.MarginContainer node) : base(uiPanel, node) { }
+ public override MarginContainer Clone() => new (UiPanel, (Godot.MarginContainer)Instance.Duplicate());
+ }
+
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: EditorForm.MarginContainer.ScrollContainer.VBoxContainer.Item.NameLabel
+ ///
+ public NameLabel S_NameLabel => L_MarginContainer.L_ScrollContainer.L_VBoxContainer.L_Item.L_NameLabel;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: EditorForm.MarginContainer.ScrollContainer.VBoxContainer.Item
+ ///
+ public Item S_Item => L_MarginContainer.L_ScrollContainer.L_VBoxContainer.L_Item;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: EditorForm.MarginContainer.ScrollContainer.VBoxContainer
+ ///
+ public VBoxContainer S_VBoxContainer => L_MarginContainer.L_ScrollContainer.L_VBoxContainer;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: EditorForm.MarginContainer.ScrollContainer
+ ///
+ public ScrollContainer S_ScrollContainer => L_MarginContainer.L_ScrollContainer;
+
+ ///
+ /// 场景中唯一名称的节点, 节点类型: , 节点路径: EditorForm.MarginContainer
+ ///
+ public MarginContainer S_MarginContainer => L_MarginContainer;
+
+}
diff --git a/DungeonShooting_Godot/src/game/ui/editorForm/EditorFormPanel.cs b/DungeonShooting_Godot/src/game/ui/editorForm/EditorFormPanel.cs
new file mode 100644
index 0000000..b581d22
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/ui/editorForm/EditorFormPanel.cs
@@ -0,0 +1,27 @@
+using Godot;
+
+namespace UI.EditorForm;
+
+///
+/// 最基础的表单显示Ui
+///
+public partial class EditorFormPanel : EditorForm
+{
+ public override void OnCreateUi()
+ {
+ S_Item.Instance.Visible = false;
+ }
+
+ ///
+ /// 添加表单元素
+ ///
+ public void AddItem(FormItemData item) where T : Control
+ {
+ var itemNode = S_Item.CloneAndPut();
+ itemNode.Instance.Visible = true;
+ itemNode.L_NameLabel.Instance.Text = item.Label + ":";
+ itemNode.AddChild(item.UiNode);
+ item.UiNode.SetHorizontalExpand(true);
+ item.UiNode.SizeFlagsStretchRatio = 80;
+ }
+}
diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorProject/TileSetEditorProjectPanel.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorProject/TileSetEditorProjectPanel.cs
index 535bda5..f5a62ef 100644
--- a/DungeonShooting_Godot/src/game/ui/tileSetEditorProject/TileSetEditorProjectPanel.cs
+++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorProject/TileSetEditorProjectPanel.cs
@@ -87,6 +87,11 @@
tileSetSourceInfo.InitData();
tileSetSourceInfo.Name = "Main";
tileSetInfo.Sources.Add(tileSetSourceInfo);
+ //默认创建一个Main Terrain, 该Terrain不可删除
+ var tileSetTerrainInfo = new TileSetTerrainInfo();
+ tileSetTerrainInfo.InitData();
+ tileSetTerrainInfo.Name = "Main";
+ tileSetSourceInfo.Terrain.Add(tileSetTerrainInfo);
split.SetTileSetInfo(tileSetInfo);
GameApplication.Instance.TileSetConfig.Add(name, split);
diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/TerrainTabCell.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/TerrainTabCell.cs
index 6e05c89..a8a4f46 100644
--- a/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/TerrainTabCell.cs
+++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/TerrainTabCell.cs
@@ -9,7 +9,15 @@
public override void OnSetData(TileSetTerrainInfo data)
{
- CellNode.Instance.Text = data.Name;
+ RefreshData();
+ }
+
+ ///
+ /// 刷新数据
+ ///
+ public void RefreshData()
+ {
+ CellNode.Instance.Text = Data.Name;
}
public override void OnSelect()
diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/TileSetEditorTerrainPanel.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/TileSetEditorTerrainPanel.cs
index dd75542..bc04723 100644
--- a/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/TileSetEditorTerrainPanel.cs
+++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/TileSetEditorTerrainPanel.cs
@@ -13,7 +13,7 @@
///
/// 当前选中的地形索引
///
- public int CurrTerrainIndex { get; set; } = -1;
+ public int CurrTerrainIndex => TerrainTabGrid.SelectIndex;
///
/// 当前选中的地形
@@ -71,11 +71,13 @@
TerrainGrid2x2 = InitTopGrid(S_TerrainRoot.L_TerrainTexture4.Instance, GameConfig.TerrainBit2x2, TileSetTerrainInfo.TerrainLayerType);
TerrainGridMiddle = InitTopGrid(S_TerrainRoot.L_TerrainTexture2.Instance, GameConfig.TerrainBitMiddle, TileSetTerrainInfo.MiddleLayerType);
TerrainGridFloor = InitTopGrid(S_TerrainRoot.L_TerrainTexture3.Instance, GameConfig.TerrainBitFloor, TileSetTerrainInfo.FloorLayerType);
-
+
//删除地形按钮
S_DeleteButton.Instance.Pressed += OnDeleteTerrainClick;
//添加地形按钮
S_AddButton.Instance.Pressed += OnAddTerrainClick;
+ //编辑地形
+ S_EditButton.Instance.Pressed += OnEditTerrainClick;
OnSetTileTexture(EditorPanel.Texture);
OnChangeTileSetBgColor(EditorPanel.BgColor);
@@ -99,18 +101,21 @@
_refreshGridConnect = false;
var terrain = CurrTerrain;
- if (terrain.TerrainType == 0) //选中47格Terrain
+ if (terrain != null)
{
- TerrainGrid3x3.ForEach(cell => RefreshConnectTerrainCell(terrain, cell));
- if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //选中Main Source
+ if (terrain.TerrainType == 0) //选中47格Terrain
{
- TerrainGridMiddle.ForEach(cell => RefreshConnectTerrainCell(terrain, cell));
- TerrainGridFloor.ForEach(cell => RefreshConnectTerrainCell(terrain, cell));
+ TerrainGrid3x3.ForEach(cell => RefreshConnectTerrainCell(terrain, cell));
+ if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //选中Main Source
+ {
+ TerrainGridMiddle.ForEach(cell => RefreshConnectTerrainCell(terrain, cell));
+ TerrainGridFloor.ForEach(cell => RefreshConnectTerrainCell(terrain, cell));
+ }
}
- }
- else //选中13格Terrain
- {
- TerrainGrid2x2.ForEach(cell => RefreshConnectTerrainCell(terrain, cell));
+ else //选中13格Terrain
+ {
+ TerrainGrid2x2.ForEach(cell => RefreshConnectTerrainCell(terrain, cell));
+ }
}
}
}
@@ -185,7 +190,12 @@
///
public void OnDropCell(MaskCell maskCell)
{
- if (CurrTerrain.TerrainType == 0) //选中47个Terrain
+ var terrain = CurrTerrain;
+ if (terrain == null)
+ {
+ return;
+ }
+ if (terrain.TerrainType == 0) //选中47个Terrain
{
var flag = true;
TerrainGrid3x3.ForEach((cell) =>
@@ -255,8 +265,6 @@
//切换选中的地形
private void OnChangeTerrain(int index)
{
- CurrTerrainIndex = index;
-
//清除所有绑定的Terrain
if (index >= 0)
{
@@ -269,18 +277,21 @@
S_BottomBg.Instance.SetHoverCell(null);
var terrain = CurrTerrain;
- if (terrain.TerrainType == 0) //选中47个Terrain
+ if (terrain != null)
{
- TerrainGrid3x3.ForEach(cell => SetTerrainCellData(terrain, cell));
- if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //选中Main Source
+ if (terrain.TerrainType == 0) //选中47个Terrain
{
- TerrainGridMiddle.ForEach(cell => SetTerrainCellData(terrain, cell));
- TerrainGridFloor.ForEach(cell => SetTerrainCellData(terrain, cell));
+ TerrainGrid3x3.ForEach(cell => SetTerrainCellData(terrain, cell));
+ if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //选中Main Source
+ {
+ TerrainGridMiddle.ForEach(cell => SetTerrainCellData(terrain, cell));
+ TerrainGridFloor.ForEach(cell => SetTerrainCellData(terrain, cell));
+ }
}
- }
- else //选中13格Terrain
- {
- TerrainGrid2x2.ForEach(cell => SetTerrainCellData(terrain, cell));
+ else //选中13格Terrain
+ {
+ TerrainGrid2x2.ForEach(cell => SetTerrainCellData(terrain, cell));
+ }
}
if (index >= 0)
@@ -343,7 +354,7 @@
{
if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //不能删除 Main Terrain
{
- EditorWindowManager.ShowTips("警告", "不允许删 Main Terrain!");
+ EditorWindowManager.ShowTips("警告", "不允许删除 Main Terrain!");
return;
}
@@ -354,15 +365,75 @@
{
if (v)
{
+ var index = TerrainTabGrid.SelectIndex;
//执行删除操作
+ EditorPanel.TileSetSourceInfo.Terrain.Remove(terrain);
+ TerrainTabGrid.RemoveByIndex(index);
+ if (index == TerrainTabGrid.Count)
+ {
+ TerrainTabGrid.SelectIndex = TerrainTabGrid.Count - 1;
+ }
+ else
+ {
+ TerrainTabGrid.SelectIndex = index;
+ }
+ EventManager.EmitEvent(EventEnum.OnTileMapDirty);
}
});
}
+ else
+ {
+ EditorWindowManager.ShowTips("提示", "清选择一个Terrain!");
+ }
}
//创建地形
private void OnAddTerrainClick()
{
+ EditorWindowManager.ShowCreateTerrain(EditorPanel.TileSetSourceInfo, terrainInfo =>
+ {
+ //执行添加操作
+ EditorPanel.TileSetSourceInfo.Terrain.Add(terrainInfo);
+ TerrainTabGrid.Add(terrainInfo, true);
+ EventManager.EmitEvent(EventEnum.OnTileMapDirty);
+ });
+ }
+
+ //编辑地形(重命名)
+ private void OnEditTerrainClick()
+ {
+ if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //不能删除 Main Terrain
+ {
+ EditorWindowManager.ShowTips("警告", "不允许重命名 Main Terrain!");
+ return;
+ }
+ var terrain = CurrTerrain;
+ if (terrain != null)
+ {
+ EditorWindowManager.ShowInput("提示", $"是否删除地形'{terrain.Name}'?", terrain.Name, (v, isClose) =>
+ {
+ if (string.IsNullOrEmpty(v))
+ {
+ EditorWindowManager.ShowTips("错误", $"名称不允许为空!");
+ return false;
+ }
+ if (terrain.Name != v && EditorPanel.TileSetSourceInfo.Terrain.FindIndex(info => info.Name == v) >= 0)
+ {
+ EditorWindowManager.ShowTips("错误", $"已经有相同名称的Terrain了!");
+ return false;
+ }
+
+ terrain.Name = v;
+ //刷新页签
+ ((TerrainTabCell)TerrainTabGrid.GetCell(CurrTerrainIndex)).RefreshData();
+ EventManager.EmitEvent(EventEnum.OnTileMapDirty);
+ return true;
+ });
+ }
+ else
+ {
+ EditorWindowManager.ShowTips("提示", "清选择一个Terrain!");
+ }
}
}
diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/up/TerrainCell.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/up/TerrainCell.cs
index 93a786d..e184418 100644
--- a/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/up/TerrainCell.cs
+++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/up/TerrainCell.cs
@@ -121,11 +121,11 @@
{
if (cellData == null)
{
- _panel.CurrTerrain.RemoveTerrainCell(Index, Data);
+ _panel.CurrTerrain?.RemoveTerrainCell(Index, Data);
}
else
{
- _panel.CurrTerrain.SetTerrainCell(Index, Data, cellData);
+ _panel.CurrTerrain?.SetTerrainCell(Index, Data, cellData);
}
EventManager.EmitEvent(EventEnum.OnTileSetDirty);
diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/up/TileEditTerrain.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/up/TileEditTerrain.cs
index 8075876..4009d20 100644
--- a/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/up/TileEditTerrain.cs
+++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorTerrain/up/TileEditTerrain.cs
@@ -36,9 +36,10 @@
{
TerrainCell cell = null;
var _panel = UiNode.UiPanel;
- if (_panel.S_TopBg.Instance.IsMouseInRect())
+ var terrain = _panel.CurrTerrain;
+ if (terrain != null && _panel.S_TopBg.Instance.IsMouseInRect())
{
- if (_panel.CurrTerrain.TerrainType == 0) //选中47个Terrain
+ if (terrain.TerrainType == 0) //选中47个Terrain
{
cell = CalcMouseHoverCell(_panel.S_TerrainTexture1.Instance, _panel.TerrainGrid3x3);
if (_panel.EditorPanel.TileSetSourceIndex == 0 && _panel.CurrTerrainIndex == 0) //选中Main Source
@@ -113,14 +114,22 @@
{
rootSize = UiNode.L_TerrainRoot.Instance.Size;
}
- else if (panel.CurrTerrain.TerrainType == 0) //选中 47 格 Terrain
+ else if (panel.CurrTerrain != null)
{
- rootSize = UiNode.L_TerrainRoot.L_TerrainTexture1.Instance.Size;
+ if (panel.CurrTerrain.TerrainType == 0) //选中 47 格 Terrain
+ {
+ rootSize = UiNode.L_TerrainRoot.L_TerrainTexture1.Instance.Size;
+ }
+ else //13 格 Terrain
+ {
+ rootSize = UiNode.L_TerrainRoot.L_TerrainTexture4.Instance.Size;
+ }
}
- else //13 格 Terrain
+ else
{
- rootSize = UiNode.L_TerrainRoot.L_TerrainTexture4.Instance.Size;
+ rootSize = Vector2.One;
}
+
Utils.DoFocusNode(ContainerRoot, Size, rootSize);
RefreshGridTrans();
}