diff --git a/data/levelGraphs/test.json b/data/levelGraphs/test.json
new file mode 100644
index 0000000..556d872
--- /dev/null
+++ b/data/levelGraphs/test.json
@@ -0,0 +1,83 @@
+{
+ "ConnectionDataList": [
+ {
+ "FromId": "c0255eb6-2c75-44f7-9058-0921fe8fb0d8",
+ "ToId": "4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03",
+ "FromPort": 0,
+ "ToPort": 0
+ },
+ {
+ "FromId": "4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03",
+ "ToId": "c604e1ef-f3e7-4189-a6f7-ab2bd23d5130",
+ "FromPort": 0,
+ "ToPort": 0
+ },
+ {
+ "FromId": "4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03",
+ "ToId": "bb9da3f9-911f-465f-af2e-be1325f17d15",
+ "FromPort": 0,
+ "ToPort": 0
+ },
+ {
+ "FromId": "c604e1ef-f3e7-4189-a6f7-ab2bd23d5130",
+ "ToId": "c9e860b9-e001-4b9b-9e6d-adf132beb64f",
+ "FromPort": 0,
+ "ToPort": 0
+ },
+ {
+ "FromId": "bb9da3f9-911f-465f-af2e-be1325f17d15",
+ "ToId": "c9e860b9-e001-4b9b-9e6d-adf132beb64f",
+ "FromPort": 0,
+ "ToPort": 0
+ }
+ ],
+ "RoomNodeDataList": [
+ {
+ "Id": "c0255eb6-2c75-44f7-9058-0921fe8fb0d8",
+ "Title": "起点房间",
+ "Description": "测试的起点房间。",
+ "RoomTemplateSet": [
+ "res://prefab/roomTemplates/dungeon/initialRoom.tscn"
+ ],
+ "Tags": [
+ "StartingRoom"
+ ]
+ },
+ {
+ "Id": "4ae948ea-82b7-4b2d-bec2-19ed8a9d4c03",
+ "Title": "大厅",
+ "Description": "比普通房间要大一些的房间,有多个门,用于连接到其他房间。",
+ "RoomTemplateSet": [
+ "res://prefab/roomTemplates/dungeon/utilityRoom.tscn"
+ ],
+ "Tags": null
+ },
+ {
+ "Id": "c604e1ef-f3e7-4189-a6f7-ab2bd23d5130",
+ "Title": "普通房间1",
+ "Description": "测试使用。",
+ "RoomTemplateSet": [
+ "res://prefab/roomTemplates/dungeon"
+ ],
+ "Tags": null
+ },
+ {
+ "Id": "bb9da3f9-911f-465f-af2e-be1325f17d15",
+ "Title": "普通房间2",
+ "Description": "测试使用。",
+ "RoomTemplateSet": [
+ "res://prefab/roomTemplates/dungeon"
+ ],
+ "Tags": null
+ },
+ {
+ "Id": "c9e860b9-e001-4b9b-9e6d-adf132beb64f",
+ "Title": "Boos房间",
+ "Description": "关卡结束的地方。",
+ "RoomTemplateSet": [
+ "res://prefab/roomTemplates/dungeon"
+ ],
+ "Tags": null
+ }
+ ]
+}
\ No newline at end of file
diff --git a/scripts/loader/sceneLoader/GameSceneLoader.cs b/scripts/loader/sceneLoader/GameSceneLoader.cs
index 549064e..66dd8cf 100644
--- a/scripts/loader/sceneLoader/GameSceneLoader.cs
+++ b/scripts/loader/sceneLoader/GameSceneLoader.cs
@@ -3,6 +3,8 @@ using ColdMint.scripts.character;
using ColdMint.scripts.debug;
using ColdMint.scripts.inventory;
using ColdMint.scripts.map;
+using ColdMint.scripts.map.LayoutParsingStrategy;
+using ColdMint.scripts.map.layoutStrategy;
using ColdMint.scripts.map.room;
using ColdMint.scripts.map.roomHolder;
using ColdMint.scripts.map.RoomPlacer;
@@ -34,6 +36,7 @@ public partial class GameSceneLoader : SceneLoaderTemplate
public override async Task LoadScene()
{
-
+ MapGenerator.LayoutStrategy = new TestLayoutStrategy();
+ MapGenerator.LayoutParsingStrategy = new SequenceLayoutParsingStrategy();
}
}
\ No newline at end of file
diff --git a/scripts/loader/sceneLoader/SceneLoaderTemplate.cs b/scripts/loader/sceneLoader/SceneLoaderTemplate.cs
index 835cfa5..6eba2aa 100644
--- a/scripts/loader/sceneLoader/SceneLoaderTemplate.cs
+++ b/scripts/loader/sceneLoader/SceneLoaderTemplate.cs
@@ -4,7 +4,7 @@ using Godot;
namespace ColdMint.scripts.loader.sceneLoader;
///
-/// 场景加载器模板
+/// The scene loader template
/// 场景加载器模板
///
public partial class SceneLoaderTemplate : Node2D, ISceneLoaderContract
diff --git a/scripts/map/ILayoutParsingStrategy.cs b/scripts/map/LayoutParsingStrategy/ILayoutParsingStrategy.cs
similarity index 95%
rename from scripts/map/ILayoutParsingStrategy.cs
rename to scripts/map/LayoutParsingStrategy/ILayoutParsingStrategy.cs
index 62c53a3..78cee3f 100644
--- a/scripts/map/ILayoutParsingStrategy.cs
+++ b/scripts/map/LayoutParsingStrategy/ILayoutParsingStrategy.cs
@@ -1,7 +1,7 @@
using System.Threading.Tasks;
using ColdMint.scripts.levelGraphEditor;
-namespace ColdMint.scripts.map;
+namespace ColdMint.scripts.map.LayoutParsingStrategy;
///
/// Layout parsing strategy
diff --git a/scripts/map/LayoutParsingStrategy/SequenceLayoutParsingStrategy.cs b/scripts/map/LayoutParsingStrategy/SequenceLayoutParsingStrategy.cs
new file mode 100644
index 0000000..73b9a2e
--- /dev/null
+++ b/scripts/map/LayoutParsingStrategy/SequenceLayoutParsingStrategy.cs
@@ -0,0 +1,215 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using ColdMint.scripts.levelGraphEditor;
+
+namespace ColdMint.scripts.map.LayoutParsingStrategy;
+
+///
+/// Sequential layout diagram parsing strategy
+/// 顺序的布局图解析策略
+///
+///
+///Traverse from the start element to the end element according to the ConnectionDataList. This policy considers the first element of the ConnectionDataList to be the fixed starting room information.
+///按照ConnectionDataList从起始元素遍历到末项元素。本策略认为ConnectionDataList的首个元素为固定的起始房间信息。
+///
+/// This policy's Next() method does not return rooms that are not connected except for the start room
+/// 本策略Next()方法不会返回除了起始房间外,没有连接的房间
+///
+public class SequenceLayoutParsingStrategy : ILayoutParsingStrategy
+{
+ private LevelGraphEditorSaveData? _levelGraphEditorSaveData;
+
+ //Check whether data Settings are valid
+ //设置数据时,是否检查合法了
+ private bool _checkLegality;
+
+ //A special marker for the starting room.
+ //特殊标记,代表起始房间。
+ private const int StartingRoomIndex = -1;
+
+ //The connection index of the query
+ //查询的连接索引
+ private int _index = StartingRoomIndex;
+ private int _maxIndex;
+ private Dictionary _roomNodeDataDictionary = new Dictionary();
+
+ public void SetLevelGraph(LevelGraphEditorSaveData levelGraphEditorSaveData)
+ {
+ _index = StartingRoomIndex;
+ _levelGraphEditorSaveData = levelGraphEditorSaveData;
+ if (_levelGraphEditorSaveData.RoomNodeDataList == null || _levelGraphEditorSaveData.RoomNodeDataList.Count == 0)
+ {
+ //No room data, unable to parse.
+ //没有房间数据,无法解析。
+ return;
+ }
+
+ if (_levelGraphEditorSaveData.ConnectionDataList == null ||
+ _levelGraphEditorSaveData.ConnectionDataList.Count == 0)
+ {
+ _maxIndex = 0;
+ }
+ else
+ {
+ _maxIndex = _levelGraphEditorSaveData.ConnectionDataList.Count - 1;
+ }
+
+ _roomNodeDataDictionary.Clear();
+ foreach (var roomNodeData in _levelGraphEditorSaveData.RoomNodeDataList)
+ {
+ if (roomNodeData.Id == null)
+ {
+ continue;
+ }
+
+ _roomNodeDataDictionary.Add(roomNodeData.Id, roomNodeData);
+ }
+
+ //Check that the first room is the starting room.
+ //检查首个房间是否为起始房间。
+ var firstRoom = GetFirstRoom(_levelGraphEditorSaveData);
+ if (firstRoom == null)
+ {
+ return;
+ }
+
+ _checkLegality = firstRoom.HasTag(Config.RoomDataTag.StartingRoom);
+ }
+
+ ///
+ /// Get the first room
+ /// 获取第一个房间
+ ///
+ ///
+ ///
+ private RoomNodeData? GetFirstRoom(LevelGraphEditorSaveData? levelGraphEditorSaveData)
+ {
+ if (levelGraphEditorSaveData == null || levelGraphEditorSaveData.RoomNodeDataList == null ||
+ levelGraphEditorSaveData.RoomNodeDataList.Count == 0)
+ {
+ return null;
+ }
+
+ RoomNodeData? firstRoom = null;
+ if (levelGraphEditorSaveData.ConnectionDataList == null ||
+ levelGraphEditorSaveData.ConnectionDataList.Count == 0)
+ {
+ //If there is no connection information, then fetch the first room in the RoomNodeDataList.
+ //如果没有连接信息,那么在RoomNodeDataList内取出第一个房间。
+ firstRoom = levelGraphEditorSaveData.RoomNodeDataList[0];
+ }
+ else
+ {
+ //If there is connection information, then fetch the first connected From room in the ConnectionDataList.
+ //如果有连接信息,那么在ConnectionDataList内取出第一个连接的From房间。
+ var firstConnection = levelGraphEditorSaveData.ConnectionDataList[0];
+ if (firstConnection.FromId == null)
+ {
+ return firstRoom;
+ }
+
+ if (_roomNodeDataDictionary.TryGetValue(firstConnection.FromId, out var value))
+ {
+ firstRoom = value;
+ }
+ }
+
+ return firstRoom;
+ }
+
+ public Task Next()
+ {
+ if (_index == StartingRoomIndex)
+ {
+ return Task.FromResult(GetFirstRoom(_levelGraphEditorSaveData));
+ }
+
+ var connectionData = GetIndexOfConnectionData(_index);
+ if (connectionData == null)
+ {
+ return Task.FromResult(null);
+ }
+
+ if (connectionData.ToId == null)
+ {
+ return Task.FromResult(null);
+ }
+
+ if (_roomNodeDataDictionary.TryGetValue(connectionData.ToId, out var value))
+ {
+ return Task.FromResult(value);
+ }
+
+ return Task.FromResult(null);
+ }
+
+ ///
+ /// Gets connection information for the specified location
+ /// 获取指定位置的连接信息
+ ///
+ ///
+ ///
+ private ConnectionData? GetIndexOfConnectionData(int index)
+ {
+ if (_levelGraphEditorSaveData == null)
+ {
+ return null;
+ }
+
+ if (_levelGraphEditorSaveData.ConnectionDataList == null ||
+ _levelGraphEditorSaveData.ConnectionDataList.Count == 0)
+ {
+ return null;
+ }
+
+ return _levelGraphEditorSaveData.ConnectionDataList[index];
+ }
+
+ public Task GetNextParentNodeId()
+ {
+ if (_index == StartingRoomIndex)
+ {
+ //The start room will not have a parent node.
+ //起始房间不会有父节点。
+ return Task.FromResult(null);
+ }
+
+ var connectionData = GetIndexOfConnectionData(_index);
+ if (connectionData == null)
+ {
+ return Task.FromResult(null);
+ }
+
+ if (connectionData.FromId == null)
+ {
+ return Task.FromResult(null);
+ }
+
+ if (_roomNodeDataDictionary.ContainsKey(connectionData.FromId))
+ {
+ return Task.FromResult(connectionData.FromId);
+ }
+
+ return Task.FromResult(null);
+ }
+
+ public Task HasNext()
+ {
+ if (!_checkLegality)
+ {
+ //If the check is not valid, then simply return false
+ //如果检查不合法,那么直接返回false
+ return Task.FromResult(false);
+ }
+
+ if (_index == StartingRoomIndex)
+ {
+ //The start room is always considered to have the next room, in order to handle situations where levelGraphEditorSaveData has only room data and no connection data.
+ //起始房间始终被认为有下一个房间,这是为了处理levelGraphEditorSaveData仅有房间数据,没有连接数据的情况。
+ _index++;
+ return Task.FromResult(true);
+ }
+
+ return Task.FromResult(_index < _maxIndex);
+ }
+}
\ No newline at end of file
diff --git a/scripts/map/MapGenerator.cs b/scripts/map/MapGenerator.cs
index 86e2419..1fa5497 100644
--- a/scripts/map/MapGenerator.cs
+++ b/scripts/map/MapGenerator.cs
@@ -2,6 +2,8 @@
using System.Threading.Tasks;
using ColdMint.scripts.debug;
using ColdMint.scripts.map.interfaces;
+using ColdMint.scripts.map.LayoutParsingStrategy;
+using ColdMint.scripts.map.layoutStrategy;
namespace ColdMint.scripts.map;
@@ -67,7 +69,8 @@ public static class MapGenerator
//Get the layout data
//拿到布局图数据
var levelGraphEditorSaveData = await _layoutStrategy.GetLayout();
- if (levelGraphEditorSaveData.RoomNodeDataList == null || levelGraphEditorSaveData.RoomNodeDataList.Count == 0)
+ if (levelGraphEditorSaveData == null || levelGraphEditorSaveData.RoomNodeDataList == null ||
+ levelGraphEditorSaveData.RoomNodeDataList.Count == 0)
{
LogCat.LogError("map_generator_attempts_to_parse_empty_layout_diagrams");
return;
diff --git a/scripts/map/ILayoutStrategy.cs b/scripts/map/layoutStrategy/ILayoutStrategy.cs
similarity index 70%
rename from scripts/map/ILayoutStrategy.cs
rename to scripts/map/layoutStrategy/ILayoutStrategy.cs
index 0bbe1d7..e38540c 100644
--- a/scripts/map/ILayoutStrategy.cs
+++ b/scripts/map/layoutStrategy/ILayoutStrategy.cs
@@ -1,7 +1,7 @@
using System.Threading.Tasks;
using ColdMint.scripts.levelGraphEditor;
-namespace ColdMint.scripts.map;
+namespace ColdMint.scripts.map.layoutStrategy;
public interface ILayoutStrategy
{
@@ -10,5 +10,5 @@ public interface ILayoutStrategy
/// 获取布局图
///
///
- public Task GetLayout();
+ public Task GetLayout();
}
\ No newline at end of file
diff --git a/scripts/map/layoutStrategy/TestLayoutStrategy.cs b/scripts/map/layoutStrategy/TestLayoutStrategy.cs
new file mode 100644
index 0000000..dad919e
--- /dev/null
+++ b/scripts/map/layoutStrategy/TestLayoutStrategy.cs
@@ -0,0 +1,32 @@
+using System.Threading.Tasks;
+using ColdMint.scripts.levelGraphEditor;
+using ColdMint.scripts.serialization;
+using Godot;
+
+namespace ColdMint.scripts.map.layoutStrategy;
+
+///
+/// Layout selection strategy to use at test time
+/// 测试时使用的布局选择策略
+///
+public class TestLayoutStrategy : ILayoutStrategy
+{
+ private string _path = "res://data/levelGraphs/test.json";
+
+ public Task GetLayout()
+ {
+ var exists = FileAccess.FileExists(_path);
+ if (!exists)
+ {
+ return Task.FromResult(null);
+ }
+
+ var json = FileAccess.GetFileAsString(_path);
+ if (json == null)
+ {
+ return Task.FromResult(null);
+ }
+
+ return Task.FromResult(JsonSerialization.Deserialize(json));
+ }
+}
\ No newline at end of file
diff --git a/scripts/serialization/JsonSerialization.cs b/scripts/serialization/JsonSerialization.cs
index 4df6c4e..8dfa329 100644
--- a/scripts/serialization/JsonSerialization.cs
+++ b/scripts/serialization/JsonSerialization.cs
@@ -43,6 +43,18 @@ public static class JsonSerialization
{
return JsonSerializer.Serialize(obj, _options);
}
+
+ ///
+ /// Deserialize Json to an object
+ /// 将Json反序列化为对象
+ ///
+ ///
+ ///
+ ///
+ public static T? Deserialize(string json)
+ {
+ return JsonSerializer.Deserialize(json, _options);
+ }
public static async Task ReadJsonFileToObj(Stream openStream)
{