diff --git "a/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.md" "b/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.md"
new file mode 100644
index 0000000..8c52557
--- /dev/null
+++ "b/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.md"
@@ -0,0 +1,14 @@
+### 2023-02-28
+进过数十天开发, 已经完成自定义房间功能, 支持配置连接门生成区域, 而不是像之前一样整个矩形外框都能生成门, 并且还做了在编辑器中可视化编辑连接们生成区域的功能
+所有的自定义房间放在`resource/map/tileMaps`, 路径下, 使用`automation`面板下的`打包地牢配置`即可将所有房间的配置信息整合到`RoomConfig.json`文件内, 方便代码获取房间数据
+在编辑器中添加`DungeonRoomTemplate`节点, 用于创建模板房间
+
+### 2023-02-15
+第一篇开发日志, 后面会更加频繁更新日志
+用了大半年事件完成完成项目基础架构搭建, 已经包含的功能有:
+* 所有物体的父物体为`ActivityObject`, 可以在编辑器中找到节点`ActivityObjectTemplate`来快速创建物体模板
+* 玩家, 敌人的基础移动, 拾起/扔掉武器, 武器袋存放武器, 切换武器, 手持武器开火, 换弹,
+* 武器类别有近战/远程武器, 武器由属性类控制
+* ai行为逻辑, 包括自动寻路, 发现玩家后追踪玩家, 通知其它ai玩家位置, 射程足够时朝玩家射击, 在玩家周围徘徊, 没有武器/弹药时寻找可用的武器
+* 随机生成地牢, 地牢房间与房间由过道连接, 一个房间至少连接一个其它房间
+* 游戏中UI, 包括血条, 玩家手持武器, 武器弹药, 换弹进度, 拾起武器提示
\ No newline at end of file
diff --git "a/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.txt" "b/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.txt"
deleted file mode 100644
index e69de29..0000000
--- "a/DungeonShooting_Document/\345\274\200\345\217\221\346\227\245\345\277\227.txt"
+++ /dev/null
diff --git a/DungeonShooting_Godot/DungeonShooting.csproj b/DungeonShooting_Godot/DungeonShooting.csproj
index cea5645..d2f5fb2 100644
--- a/DungeonShooting_Godot/DungeonShooting.csproj
+++ b/DungeonShooting_Godot/DungeonShooting.csproj
@@ -1,4 +1,4 @@
-
+
net6.0
true
diff --git a/DungeonShooting_Godot/DungeonShooting.csproj.old b/DungeonShooting_Godot/DungeonShooting.csproj.old
deleted file mode 100644
index cdcc424..0000000
--- a/DungeonShooting_Godot/DungeonShooting.csproj.old
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- net472
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/DungeonShooting_Godot/DungeonShooting.csproj.old.1 b/DungeonShooting_Godot/DungeonShooting.csproj.old.1
deleted file mode 100644
index dd1e7a3..0000000
--- a/DungeonShooting_Godot/DungeonShooting.csproj.old.1
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- net6.0
- true
-
-
\ No newline at end of file
diff --git a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Automation.cs b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Automation.cs
index c98af3c..d33af7d 100644
--- a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Automation.cs
+++ b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Automation.cs
@@ -1,6 +1,9 @@
#if TOOLS
+using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text.Json;
using System.Text.RegularExpressions;
using Godot;
using File = System.IO.File;
@@ -11,7 +14,7 @@
//支持后缀
private string[] suffix =
{
- ".png", ".jpg", ".txt", ".json", ".ini", ".tscn", ".tres", ".otf", ".gdshader", ".tmx", ".tsx", ".ogg", ".mp3", ".wav", ".svg"
+ ".png", ".jpg", ".txt", ".json", ".ini", ".tscn", ".tres", ".otf", ".gdshader", ".ogg", ".mp3", ".wav", ".svg"
};
//排除第一层的文件夹
private string[] exclude =
@@ -22,7 +25,9 @@
private string resultStr = "";
- //更新 ResourcePath
+ ///
+ /// 更新 ResourcePath
+ ///
private void _on_Button_pressed()
{
resultStr = "/// \n" +
@@ -56,6 +61,94 @@
GD.Print("ResourcePath.cs 写出完成!");
}
+ ///
+ /// 重新打包房间配置
+ ///
+ private void _on_Button2_pressed()
+ {
+ //地图路径
+ var tileDir = DungeonRoomTemplate.RoomTileDir;
+ //地图描述数据路径
+ var tileDataDir = DungeonRoomTemplate.RoomTileDataDir;
+
+ var tileDirInfo = new DirectoryInfo(tileDir);
+ var tileDataDirInfo = new DirectoryInfo(tileDataDir);
+
+ //所有地图列表
+ var mapList = new HashSet();
+
+ //收集所有名称
+ var fileDataInfos = tileDataDirInfo.GetFiles();
+ foreach (var fileInfo in fileDataInfos)
+ {
+ mapList.Add(RemoveExtension(fileInfo.Name));
+ }
+ //收集所有名称
+ var fileInfos = tileDirInfo.GetFiles();
+ foreach (var fileInfo in fileInfos)
+ {
+ if (fileInfo.Extension == ".tscn")
+ {
+ mapList.Add(RemoveExtension(fileInfo.Name));
+ }
+ }
+
+ //剔除多余的 tile.json
+ var arrays = mapList.ToArray();
+ foreach (var item in arrays)
+ {
+ if (!File.Exists(tileDir + item + ".tscn"))
+ {
+ mapList.Remove(item);
+ var filePath = tileDataDir + item + ".json";
+ if (File.Exists(filePath))
+ {
+ GD.Print($"未找到'{tileDir + item}.tscn', 删除配置文件: {filePath}");
+ File.Delete(filePath);
+ }
+ }
+ }
+
+ //手动生成缺失的 tile.json
+ foreach (var item in mapList)
+ {
+ if (!File.Exists(tileDataDir + item + ".json"))
+ {
+ var tscnName = tileDir + item + ".tscn";
+ var packedScene = ResourceManager.Load(tscnName, false);
+ if (packedScene != null)
+ {
+ var dungeonRoomTemplate = packedScene.Instantiate();
+ var usedRect = dungeonRoomTemplate.GetUsedRect();
+ DungeonRoomTemplate.SaveConfig(new List(), usedRect.Position, usedRect.Size, item);
+ dungeonRoomTemplate.QueueFree();
+ }
+ }
+ }
+
+ var list = new List();
+ //整合操作
+ foreach (var item in mapList)
+ {
+ var configPath = tileDataDir + item + ".json";
+ var configText = File.ReadAllText(configPath);
+ var roomInfo = DungeonRoomTemplate.DeserializeDungeonRoomInfo(configText);
+ var split = new DungeonRoomSplit();
+ split.ScenePath = ToResPath(tileDir + item + ".tscn");
+ split.ConfigPath = ToResPath(configPath);
+ split.RoomInfo = roomInfo;
+ list.Add(split);
+ }
+
+ //写出配置
+ var config = new JsonSerializerOptions();
+ config.WriteIndented = true;
+ var text = JsonSerializer.Serialize(list, config);
+ File.WriteAllText(DungeonRoomTemplate.RoomTileConfigFile, text);
+
+ GD.Print("地牢房间配置, 重新打包完成!");
+ }
+
private void EachDir(DirectoryInfo directoryInfos)
{
var fileInfos = directoryInfos.GetFiles();
@@ -84,5 +177,23 @@
resultStr += $" public const string {field} = \"{resPath}\";\n";
}
}
+
+ private string ToResPath(string path)
+ {
+ var field = path.Substring(currDir.Length + 1);
+ field = field.Replace("\\", "/");
+ return "res://" + field;
+ }
+
+ private string RemoveExtension(string name)
+ {
+ var index = name.LastIndexOf(".", StringComparison.Ordinal);
+ if (index >= 0)
+ {
+ return name.Substring(0, index);
+ }
+
+ return name;
+ }
}
#endif
\ No newline at end of file
diff --git a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Automation.tscn b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Automation.tscn
index 89e7ef5..66d1942 100644
--- a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Automation.tscn
+++ b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Automation.tscn
@@ -1,34 +1,46 @@
-[gd_scene load_steps=2 format=2]
+[gd_scene load_steps=2 format=3 uid="uid://bygnukrvvm1vi"]
-[ext_resource path="res://addons/dungeonShooting_plugin/Automation.cs" type="Script" id=1]
+[ext_resource type="Script" path="res://addons/dungeonShooting_plugin/Automation.cs" id="1"]
[node name="Automation" type="Control"]
+layout_mode = 3
+anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
-script = ExtResource( 1 )
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("1")
[node name="ScrollContainer" type="ScrollContainer" parent="."]
+layout_mode = 0
anchor_right = 1.0
anchor_bottom = 1.0
[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"]
-offset_right = 1920.0
-offset_bottom = 35.0
+layout_mode = 2
size_flags_horizontal = 3
[node name="HBoxContainer" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
-offset_right = 1920.0
-offset_bottom = 35.0
+layout_mode = 2
[node name="Label" type="Label" parent="ScrollContainer/VBoxContainer/HBoxContainer"]
-offset_right = 158.0
-offset_bottom = 35.0
+layout_mode = 2
text = "ResourcePath.cs"
[node name="Button" type="Button" parent="ScrollContainer/VBoxContainer/HBoxContainer"]
-offset_left = 162.0
-offset_right = 246.0
-offset_bottom = 35.0
+layout_mode = 2
text = "重新生成"
+[node name="HBoxContainer2" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="ScrollContainer/VBoxContainer/HBoxContainer2"]
+layout_mode = 2
+text = "地牢房间配置"
+
+[node name="Button" type="Button" parent="ScrollContainer/VBoxContainer/HBoxContainer2"]
+layout_mode = 2
+text = "重新打包"
+
[connection signal="pressed" from="ScrollContainer/VBoxContainer/HBoxContainer/Button" to="." method="_on_Button_pressed"]
+[connection signal="pressed" from="ScrollContainer/VBoxContainer/HBoxContainer2/Button" to="." method="_on_Button2_pressed"]
diff --git a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Map.svg b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Map.svg
new file mode 100644
index 0000000..53529e1
--- /dev/null
+++ b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Map.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Map.svg.import b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Map.svg.import
new file mode 100644
index 0000000..c664f8f
--- /dev/null
+++ b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Map.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://downmhbbm43yu"
+path="res://.godot/imported/Map.svg-dcee5d8c5d80d0921a3de443b022f3d9.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/dungeonShooting_plugin/Map.svg"
+dest_files=["res://.godot/imported/Map.svg-dcee5d8c5d80d0921a3de443b022f3d9.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Plugin.cs b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Plugin.cs
index 89526b8..5d60ede 100644
--- a/DungeonShooting_Godot/addons/dungeonShooting_plugin/Plugin.cs
+++ b/DungeonShooting_Godot/addons/dungeonShooting_plugin/Plugin.cs
@@ -22,6 +22,10 @@
var script = GD.Load