diff --git a/README.md b/README.md
index 09a6691..9d4f2f6 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ English [简体中文](README_ZH.md) [にほんご](README_JP.md)
Mint's new game.
-A pixel cross-platform Roguelite game.
+A pixel cross-platform roguelite game.
## Recent Development progress
@@ -14,6 +14,16 @@ A pixel cross-platform Roguelite game.
| loot | await |
| Support still out of the knapsack system | await |
+## Screenshot
+
+Game scene
+
+![](screenshot\0.0.1\game_page.png)
+
+Level graph editor
+
+![](screenshot\0.0.1\level_Graph_Editor.png)
+
## Run the project locally
#### Download engine
diff --git a/README_JP.md b/README_JP.md
index d30cb0f..b78b223 100644
--- a/README_JP.md
+++ b/README_JP.md
@@ -1,4 +1,4 @@
-[English](README.md) [简体中文](README_ZH) にほんご
+[English](README.md) [简体中文](README_ZH.md) にほんご
## こくじ
@@ -13,7 +13,15 @@
| マップをランダムに生成します | 進行中です |
| 戦利品 | すたんばい |
| バックパックのシステムをサポートしています | すたんばい |
+## スクリーンショットです
+ゲームのシーンです
+
+![](screenshot\0.0.1\game_page.png)
+
+ステージエディター
+
+![](screenshot\0.0.1\level_Graph_Editor.png)
## 地元でプロジェクトを進めています
#### ダウンロードエンジンです
diff --git a/README_ZH.md b/README_ZH.md
index c7e058b..87222c3 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -14,6 +14,16 @@
| 战利品 | 等待 |
| 支持仍出的背包系统 | 等待 |
+## 屏幕截图
+
+游戏场景
+
+![](screenshot\0.0.1\game_page.png)
+
+关卡编辑器
+
+![](screenshot\0.0.1\level_Graph_Editor.png)
+
## 在本地运行项目
#### 下载引擎
diff --git a/locals/Error.csv b/locals/Error.csv
index 90bdb00..add28cc 100644
--- a/locals/Error.csv
+++ b/locals/Error.csv
@@ -4,4 +4,6 @@ missing_parameters,缺少参数。,Missing parameters.,パラメータが不足
room_root_node_must_be_node2d,房间根节点必须是 Node2D。,Room root node must be Node2D.,ルートノードはNode2Dでなければなりません。
width_or_height_of_room_slot_must_be_1,房间槽的宽度或高度必须为1。,The width or height of the room slot must be 1.,部屋の溝の幅または高さは1でなければなりません。
connected_room_timeout,连接房间超时。,Connecting the room timed out.,接続部屋はタイムアウトです。
-projectiles_is_empty,未设置抛射体。,The projectile is not set.,射出体は設置されていません。
\ No newline at end of file
+projectiles_is_empty,未设置抛射体。,The projectile is not set.,射出体は設置されていません。
+map_generator_missing_parameters,地图生成器缺少参数。,Map generator missing parameters.,マップジェネレータが不足しています。
+map_generator_attempts_to_parse_empty_layout_diagrams,地图生成器尝试解析空的布局图。,Map generator attempts to parse empty layout diagrams.,マップジェネレータは空のレイアウト図を解析しようとしています。
\ No newline at end of file
diff --git a/locals/Error.en.translation b/locals/Error.en.translation
index 6bd3e94..262938c 100644
Binary files a/locals/Error.en.translation and b/locals/Error.en.translation differ
diff --git a/locals/Error.jp.translation b/locals/Error.jp.translation
index a8edd94..50361d6 100644
Binary files a/locals/Error.jp.translation and b/locals/Error.jp.translation differ
diff --git a/locals/Error.zh.translation b/locals/Error.zh.translation
index 701d03f..6e08a5e 100644
Binary files a/locals/Error.zh.translation and b/locals/Error.zh.translation differ
diff --git a/screenshot/0.0.1/game_page.png b/screenshot/0.0.1/game_page.png
new file mode 100644
index 0000000..a0d6f8b
Binary files /dev/null and b/screenshot/0.0.1/game_page.png differ
diff --git a/screenshot/0.0.1/game_page.png.import b/screenshot/0.0.1/game_page.png.import
new file mode 100644
index 0000000..b97fcb0
--- /dev/null
+++ b/screenshot/0.0.1/game_page.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b4r8qekdrtgbv"
+path="res://.godot/imported/game_page.png-f8f5cdcc23f5b71be114ec8661e808ce.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://screenshot/0.0.1/game_page.png"
+dest_files=["res://.godot/imported/game_page.png-f8f5cdcc23f5b71be114ec8661e808ce.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
diff --git a/screenshot/0.0.1/level_Graph_Editor.png b/screenshot/0.0.1/level_Graph_Editor.png
new file mode 100644
index 0000000..c9b3513
Binary files /dev/null and b/screenshot/0.0.1/level_Graph_Editor.png differ
diff --git a/screenshot/0.0.1/level_Graph_Editor.png.import b/screenshot/0.0.1/level_Graph_Editor.png.import
new file mode 100644
index 0000000..2924e6d
--- /dev/null
+++ b/screenshot/0.0.1/level_Graph_Editor.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dyiarx2q4r6y6"
+path="res://.godot/imported/level_Graph_Editor.png-2a8ba6f35e054e058aaed64bd42cfc40.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://screenshot/0.0.1/level_Graph_Editor.png"
+dest_files=["res://.godot/imported/level_Graph_Editor.png-2a8ba6f35e054e058aaed64bd42cfc40.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
diff --git a/scripts/map/ILayoutParsingStrategy.cs b/scripts/map/ILayoutParsingStrategy.cs
new file mode 100644
index 0000000..62c53a3
--- /dev/null
+++ b/scripts/map/ILayoutParsingStrategy.cs
@@ -0,0 +1,39 @@
+using System.Threading.Tasks;
+using ColdMint.scripts.levelGraphEditor;
+
+namespace ColdMint.scripts.map;
+
+///
+/// Layout parsing strategy
+/// 布局图解析策略
+///
+public interface ILayoutParsingStrategy
+{
+ ///
+ /// Sets the layout diagram to parse
+ /// 设置要解析的布局图
+ ///
+ ///
+ public void SetLevelGraph(LevelGraphEditorSaveData levelGraphEditorSaveData);
+
+ ///
+ /// Gets the next room to place
+ /// 获取下一个要放置的房间
+ ///
+ ///
+ public Task Next();
+
+ ///
+ /// Gets the ID of the next parent node to place
+ /// 获取下一个要放置的父节点ID
+ ///
+ ///
+ public Task GetNextParentNodeId();
+
+ ///
+ /// Is there another room that needs to be placed
+ /// 是否还有下一个需要放置的房间
+ ///
+ ///
+ public Task HasNext();
+}
\ No newline at end of file
diff --git a/scripts/map/IRoomInjectionStrategy.cs b/scripts/map/IRoomInjectionStrategy.cs
new file mode 100644
index 0000000..3f33fc8
--- /dev/null
+++ b/scripts/map/IRoomInjectionStrategy.cs
@@ -0,0 +1,10 @@
+namespace ColdMint.scripts.map;
+
+///
+/// Room injection strategy
+/// 房间注入策略
+///
+public interface IRoomInjectionStrategy
+{
+
+}
\ No newline at end of file
diff --git a/scripts/map/MapGenerator.cs b/scripts/map/MapGenerator.cs
index 03daf44..86e2419 100644
--- a/scripts/map/MapGenerator.cs
+++ b/scripts/map/MapGenerator.cs
@@ -1,5 +1,7 @@
-using System.Threading.Tasks;
-using ColdMint.scripts.levelGraphEditor;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using ColdMint.scripts.debug;
+using ColdMint.scripts.map.interfaces;
namespace ColdMint.scripts.map;
@@ -19,6 +21,31 @@ public static class MapGenerator
///
private static ILayoutStrategy? _layoutStrategy;
+ ///
+ /// Room placement strategy
+ /// 房间的放置策略
+ ///
+ private static IRoomPlacementStrategy? _roomPlacementStrategy;
+
+
+ ///
+ /// Layout diagram parsing policy
+ /// 布局图解析策略
+ ///
+ private static ILayoutParsingStrategy? _layoutParsingStrategy;
+
+ public static ILayoutParsingStrategy? LayoutParsingStrategy
+ {
+ get => _layoutParsingStrategy;
+ set => _layoutParsingStrategy = value;
+ }
+
+ public static IRoomPlacementStrategy? RoomPlacementStrategy
+ {
+ get => _roomPlacementStrategy;
+ set => _roomPlacementStrategy = value;
+ }
+
public static ILayoutStrategy? LayoutStrategy
{
get => _layoutStrategy;
@@ -31,30 +58,62 @@ public static class MapGenerator
///
public static async Task GenerateMap()
{
- if (_layoutStrategy == null)
+ if (_layoutStrategy == null || _roomPlacementStrategy == null || _layoutParsingStrategy == null)
{
+ LogCat.LogError("map_generator_missing_parameters");
return;
}
//Get the layout data
//拿到布局图数据
var levelGraphEditorSaveData = await _layoutStrategy.GetLayout();
- //Finding the starting room
- //查找起点房间
if (levelGraphEditorSaveData.RoomNodeDataList == null || levelGraphEditorSaveData.RoomNodeDataList.Count == 0)
{
+ LogCat.LogError("map_generator_attempts_to_parse_empty_layout_diagrams");
return;
}
- var startRoomNodeData = levelGraphEditorSaveData.RoomNodeDataList.Find(roomNodeData =>
- roomNodeData.HasTag(Config.RoomDataTag.StartingRoom));
- if (startRoomNodeData == null)
+ _layoutParsingStrategy.SetLevelGraph(levelGraphEditorSaveData);
+ //Save the dictionary, put the ID in the room data, corresponding to the successful placement of the room.
+ //保存字典,将房间数据内的ID,对应放置成功的房间。
+ var roomDictionary = new Dictionary();
+ while (await _layoutParsingStrategy.HasNext())
{
- //Can't find the starting room
- //找不到起点房间
- return;
+ //When a new room needs to be placed
+ //当有新的房间需要放置时
+ var roomNodeData = await _layoutParsingStrategy.Next();
+ if (roomNodeData == null)
+ {
+ continue;
+ }
+
+ var nextParentNodeId = await _layoutParsingStrategy.GetNextParentNodeId();
+ IRoom? parentRoomNode = null;
+ if (nextParentNodeId != null)
+ {
+ //If the new room has the parent's ID, then we pass the parent's room into the compute function.
+ //如果新房间有父节点的ID,那么我们将父节点的房间传入到计算函数内。
+ parentRoomNode = roomDictionary[nextParentNodeId];
+ }
+
+ var roomPlacementData =
+ await _roomPlacementStrategy.CalculateNewRoomPlacementData(parentRoomNode, roomNodeData);
+ if (roomPlacementData == null)
+ {
+ continue;
+ }
+
+ if (!await _roomPlacementStrategy.PlaceRoom(roomPlacementData))
+ {
+ continue;
+ }
+
+ if (!string.IsNullOrEmpty(roomNodeData.Id) && roomPlacementData.Room != null)
+ {
+ roomDictionary.Add(roomNodeData.Id, roomPlacementData.Room);
+ }
}
- //The starting room is regarded as the root node, and the map is generated from the root node to the leaf node like the tree structure.
- //TODO:将起点房间看作根节点,像树结构一样,从根节点到叶节点生成地图。
+ //All rooms have been placed.
+ //所有房间已放置完毕。
}
}
\ No newline at end of file
diff --git a/scripts/map/dateBean/RoomPlacementData.cs b/scripts/map/dateBean/RoomPlacementData.cs
new file mode 100644
index 0000000..60b1040
--- /dev/null
+++ b/scripts/map/dateBean/RoomPlacementData.cs
@@ -0,0 +1,22 @@
+using ColdMint.scripts.map.interfaces;
+using Godot;
+
+namespace ColdMint.scripts.map.dateBean;
+
+///
+/// Room placement information
+/// 房间放置信息
+///
+public class RoomPlacementData
+{
+ ///
+ /// the location of placement
+ /// 放置的位置
+ ///
+ public Vector2? Position { get; set; }
+ ///
+ /// Place the room template
+ /// 放置的房间模板
+ ///
+ public IRoom? Room { get; set; }
+}
\ No newline at end of file
diff --git a/scripts/map/interfaces/IBranch.cs b/scripts/map/interfaces/IBranch.cs
deleted file mode 100644
index 715ed9a..0000000
--- a/scripts/map/interfaces/IBranch.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace ColdMint.scripts.map.interfaces;
-
-///
-/// Represents a branch on the map.
-/// 表示地图上的一个分支。
-///
-public interface IBranch
-{
- ///
- /// Master branch or not
- /// 是否为主分支
- ///
- bool IsMasterBranch
- {
- get;
- set;
- }
-}
\ No newline at end of file
diff --git a/scripts/map/interfaces/IRoom.cs b/scripts/map/interfaces/IRoom.cs
index 5164fab..ac10671 100644
--- a/scripts/map/interfaces/IRoom.cs
+++ b/scripts/map/interfaces/IRoom.cs
@@ -15,6 +15,10 @@ public interface IRoom
///
PackedScene? RoomScene { get; set; }
+ ///
+ /// Tile map
+ /// 瓦片地图
+ ///
TileMap? TileMap { get; set; }
///
diff --git a/scripts/map/interfaces/IRoomPlacementStrategy.cs b/scripts/map/interfaces/IRoomPlacementStrategy.cs
new file mode 100644
index 0000000..e90ad20
--- /dev/null
+++ b/scripts/map/interfaces/IRoomPlacementStrategy.cs
@@ -0,0 +1,41 @@
+using System.Threading.Tasks;
+using ColdMint.scripts.levelGraphEditor;
+using ColdMint.scripts.map.dateBean;
+
+namespace ColdMint.scripts.map.interfaces;
+
+///
+/// Room placement strategy
+/// 房间放置策略
+///
+public interface IRoomPlacementStrategy
+{
+ ///
+ /// Place the room in the designated location
+ /// 在指定的位置放置房间
+ ///
+ ///
+ ///Room placement information
+ ///房间放置信息
+ ///
+ ///
+ ///Placement success or not
+ ///是否放置成功
+ ///
+ public Task PlaceRoom(RoomPlacementData roomPlacementData);
+
+ ///
+ /// Calculate new room placement information
+ /// 计算新的房间放置信息
+ ///
+ ///
+ ///Parent room node
+ ///父房间节点
+ ///
+ ///
+ ///New room data to be placed
+ ///欲放置的新房间数据
+ ///
+ ///
+ public Task CalculateNewRoomPlacementData(IRoom? parentRoomNode, RoomNodeData newRoomNodeData);
+}
\ No newline at end of file
diff --git a/scripts/map/interfaces/IRoomPlacer.cs b/scripts/map/interfaces/IRoomPlacer.cs
deleted file mode 100644
index 1622f4b..0000000
--- a/scripts/map/interfaces/IRoomPlacer.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Threading.Tasks;
-using ColdMint.scripts.map.dateBean;
-using ColdMint.scripts.map.RoomPlacer;
-using Godot;
-
-namespace ColdMint.scripts.map.interfaces;
-
-///
-/// Room placer
-/// 房间放置器
-///
-///
-///Responsible for arranging the rooms on the map
-///负责在地图中摆放房间
-///
-public interface IRoomPlacer
-{
-
- ///
- /// Place the room in the designated location
- /// 在指定的位置放置房间
- ///
- ///
- ///
- ///
- public Task PlaceRoom(Vector2 position, IRoom room);
-
- ///
- /// Pass into two rooms and calculate the location of the new room
- /// 传入两个房间,计算新房间的位置
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public Task CalculatedPosition(IRoom mainRoom, IRoom newRoom, RoomSlot? mainRoomSlot, RoomSlot? newRoomSlot,
- RoomPlacerConfig roomPlacerConfig);
-}
\ No newline at end of file
diff --git a/scripts/map/roomPlacer/PatchworkRoomPlacementStrategy.cs b/scripts/map/roomPlacer/PatchworkRoomPlacementStrategy.cs
new file mode 100644
index 0000000..9e91a2b
--- /dev/null
+++ b/scripts/map/roomPlacer/PatchworkRoomPlacementStrategy.cs
@@ -0,0 +1,34 @@
+using System.Threading.Tasks;
+using ColdMint.scripts.levelGraphEditor;
+using ColdMint.scripts.map.dateBean;
+using ColdMint.scripts.map.interfaces;
+using Godot;
+
+namespace ColdMint.scripts.map.RoomPlacer;
+
+///
+/// Patchwork room placement strategy
+/// 拼接的房间放置策略
+///
+///
+///Under this strategy, think of each room template as a puzzle piece, find their "slots", and then connect them together.
+///在此策略下,将每个房间模板看作是一块拼图,找到他们的“槽”,然后将其连接在一起。
+///
+public class PatchworkRoomPlacementStrategy : IRoomPlacementStrategy
+{
+ public Task PlaceRoom(RoomPlacementData roomPlacementData)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public Task GetStartRoomPlacementData(RoomNodeData startRoomNodeData)
+ {
+ throw new System.NotImplementedException();
+ }
+
+
+ public Task CalculateNewRoomPlacementData(IRoom parentRoomNode, RoomNodeData newRoomNodeData)
+ {
+ throw new System.NotImplementedException();
+ }
+}
\ No newline at end of file
diff --git a/scripts/map/roomPlacer/RoomPlacer.cs b/scripts/map/roomPlacer/RoomPlacer.cs
deleted file mode 100644
index 13ed493..0000000
--- a/scripts/map/roomPlacer/RoomPlacer.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using System.Threading.Tasks;
-using ColdMint.scripts.map.dateBean;
-using ColdMint.scripts.map.interfaces;
-using Godot;
-using static ColdMint.scripts.Config;
-
-namespace ColdMint.scripts.map.RoomPlacer;
-
-public class RoomPlacer : RoomPlacerTemplate
-{
- public IMapGeneratorConfig? MapGeneratorConfig { get; set; }
- private readonly Vector2 _halfCell = new Vector2(CellSize / 2f, CellSize / 2f);
-
- public override Task PlaceRoom(Vector2 position, IRoom room)
- {
- if (MapGeneratorConfig == null)
- {
- return Task.FromResult(false);
- }
-
- var node = room.RootNode;
- MapGeneratorConfig.MapRoot.AddChild(node);
- if (node is { } node2D)
- {
- //If the Node is not empty and is a 2D node.
- //如果Node不是空的,且是2D节点。
- node2D.Position = position;
- return Task.FromResult(true);
- }
-
- return Task.FromResult(false);
- }
-
- public override Task CalculatedPosition(IRoom mainRoom, IRoom newRoom, RoomSlot? mainRoomSlot,
- RoomSlot? newRoomSlot,
- RoomPlacerConfig roomPlacerConfig)
- {
- if (mainRoom.RootNode == null || mainRoom.TileMap == null || newRoom.TileMap == null || mainRoomSlot == null ||
- newRoomSlot == null)
- {
- return Task.FromResult(Vector2.Zero);
- }
-
- //计算主插槽中点在世界中的位置。
- //mainRoom.RootNode.Position意为房间所在的世界位置
- //mainRoom.TileMap.MapToLocal(mainRoomSlot.StartPosition)意为主插槽在房间中的位置
- var result = mainRoom.RootNode.Position + mainRoom.TileMap.MapToLocal(mainRoomSlot.StartPosition);
- if (roomPlacerConfig.RoomSlotOverlap)
- {
- //执行减法,从槽中点偏移到左上角
- result -= _halfCell;
- }
- else
- {
- //执行减法,从槽中点偏移到右下角
- result += _halfCell;
- }
- //我们不能将新房间的原点设置在主房间槽的左上角或右下角,这会导致插槽不对应。
-
- //竖直槽,我们需要在同一水平上。
- if (mainRoomSlot.IsHorizontal)
- {
- result += newRoom.TileMap.MapToLocal(new Vector2I(newRoomSlot.EndPosition.X, 0)) - _halfCell;
- }
- else
- {
- result -= newRoom.TileMap.MapToLocal(new Vector2I(0, newRoomSlot.EndPosition.Y)) - _halfCell;
- }
-
- return Task.FromResult(result);
- }
-}
\ No newline at end of file
diff --git a/scripts/map/roomPlacer/RoomPlacerTemplate.cs b/scripts/map/roomPlacer/RoomPlacerTemplate.cs
deleted file mode 100644
index 99557a2..0000000
--- a/scripts/map/roomPlacer/RoomPlacerTemplate.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Threading.Tasks;
-using ColdMint.scripts.map.dateBean;
-using ColdMint.scripts.map.interfaces;
-using Godot;
-
-namespace ColdMint.scripts.map.RoomPlacer;
-
-public abstract class RoomPlacerTemplate : IRoomPlacer
-{
- public abstract Task PlaceRoom(Vector2 position, IRoom room);
-
- public abstract Task CalculatedPosition(IRoom mainRoom, IRoom newRoom, RoomSlot? mainRoomSlot, RoomSlot? newRoomSlot,
- RoomPlacerConfig roomPlacerConfig);
-}
\ No newline at end of file