Adjust the map generator.
调整地图生成器。
This commit is contained in:
parent
dd2577cfd0
commit
529d5e95b5
|
@ -1,22 +1,15 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ColdMint.scripts.character;
|
|
||||||
using ColdMint.scripts.debug;
|
|
||||||
using ColdMint.scripts.inventory;
|
using ColdMint.scripts.inventory;
|
||||||
using ColdMint.scripts.map;
|
using ColdMint.scripts.map;
|
||||||
using ColdMint.scripts.map.LayoutParsingStrategy;
|
using ColdMint.scripts.map.LayoutParsingStrategy;
|
||||||
using ColdMint.scripts.map.layoutStrategy;
|
using ColdMint.scripts.map.layoutStrategy;
|
||||||
using ColdMint.scripts.map.room;
|
|
||||||
using ColdMint.scripts.map.roomHolder;
|
|
||||||
using ColdMint.scripts.map.RoomPlacer;
|
using ColdMint.scripts.map.RoomPlacer;
|
||||||
using ColdMint.scripts.map.RoomProvider;
|
|
||||||
using ColdMint.scripts.map.slotsMatcher;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace ColdMint.scripts.loader.sceneLoader;
|
namespace ColdMint.scripts.loader.sceneLoader;
|
||||||
|
|
||||||
public partial class GameSceneLoader : SceneLoaderTemplate
|
public partial class GameSceneLoader : SceneLoaderTemplate
|
||||||
{
|
{
|
||||||
|
|
||||||
public override Task InitializeData()
|
public override Task InitializeData()
|
||||||
{
|
{
|
||||||
//加载血条场景
|
//加载血条场景
|
||||||
|
@ -36,7 +29,10 @@ public partial class GameSceneLoader : SceneLoaderTemplate
|
||||||
|
|
||||||
public override async Task LoadScene()
|
public override async Task LoadScene()
|
||||||
{
|
{
|
||||||
|
MapGenerator.MapRoot = GetNode<Node>("MapRoot");
|
||||||
MapGenerator.LayoutStrategy = new TestLayoutStrategy();
|
MapGenerator.LayoutStrategy = new TestLayoutStrategy();
|
||||||
MapGenerator.LayoutParsingStrategy = new SequenceLayoutParsingStrategy();
|
MapGenerator.LayoutParsingStrategy = new SequenceLayoutParsingStrategy();
|
||||||
|
MapGenerator.RoomPlacementStrategy = new PatchworkRoomPlacementStrategy();
|
||||||
|
await MapGenerator.GenerateMap();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,6 +4,8 @@ using ColdMint.scripts.debug;
|
||||||
using ColdMint.scripts.map.interfaces;
|
using ColdMint.scripts.map.interfaces;
|
||||||
using ColdMint.scripts.map.LayoutParsingStrategy;
|
using ColdMint.scripts.map.LayoutParsingStrategy;
|
||||||
using ColdMint.scripts.map.layoutStrategy;
|
using ColdMint.scripts.map.layoutStrategy;
|
||||||
|
using ColdMint.scripts.map.room;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
namespace ColdMint.scripts.map;
|
namespace ColdMint.scripts.map;
|
||||||
|
|
||||||
|
@ -23,6 +25,12 @@ public static class MapGenerator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static ILayoutStrategy? _layoutStrategy;
|
private static ILayoutStrategy? _layoutStrategy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Map root node</para>
|
||||||
|
/// <para>地图根节点</para>
|
||||||
|
/// </summary>
|
||||||
|
private static Node? _mapRoot;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Room placement strategy</para>
|
/// <para>Room placement strategy</para>
|
||||||
/// <para>房间的放置策略</para>
|
/// <para>房间的放置策略</para>
|
||||||
|
@ -36,6 +44,12 @@ public static class MapGenerator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static ILayoutParsingStrategy? _layoutParsingStrategy;
|
private static ILayoutParsingStrategy? _layoutParsingStrategy;
|
||||||
|
|
||||||
|
public static Node? MapRoot
|
||||||
|
{
|
||||||
|
get => _mapRoot;
|
||||||
|
set => _mapRoot = value;
|
||||||
|
}
|
||||||
|
|
||||||
public static ILayoutParsingStrategy? LayoutParsingStrategy
|
public static ILayoutParsingStrategy? LayoutParsingStrategy
|
||||||
{
|
{
|
||||||
get => _layoutParsingStrategy;
|
get => _layoutParsingStrategy;
|
||||||
|
@ -60,7 +74,8 @@ public static class MapGenerator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static async Task GenerateMap()
|
public static async Task GenerateMap()
|
||||||
{
|
{
|
||||||
if (_layoutStrategy == null || _roomPlacementStrategy == null || _layoutParsingStrategy == null)
|
if (_layoutStrategy == null || _roomPlacementStrategy == null || _layoutParsingStrategy == null ||
|
||||||
|
_mapRoot == null)
|
||||||
{
|
{
|
||||||
LogCat.LogError("map_generator_missing_parameters");
|
LogCat.LogError("map_generator_missing_parameters");
|
||||||
return;
|
return;
|
||||||
|
@ -79,7 +94,7 @@ public static class MapGenerator
|
||||||
_layoutParsingStrategy.SetLevelGraph(levelGraphEditorSaveData);
|
_layoutParsingStrategy.SetLevelGraph(levelGraphEditorSaveData);
|
||||||
//Save the dictionary, put the ID in the room data, corresponding to the successful placement of the room.
|
//Save the dictionary, put the ID in the room data, corresponding to the successful placement of the room.
|
||||||
//保存字典,将房间数据内的ID,对应放置成功的房间。
|
//保存字典,将房间数据内的ID,对应放置成功的房间。
|
||||||
var roomDictionary = new Dictionary<string, IRoom>();
|
var roomDictionary = new Dictionary<string, Room>();
|
||||||
while (await _layoutParsingStrategy.HasNext())
|
while (await _layoutParsingStrategy.HasNext())
|
||||||
{
|
{
|
||||||
//When a new room needs to be placed
|
//When a new room needs to be placed
|
||||||
|
@ -91,12 +106,15 @@ public static class MapGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextParentNodeId = await _layoutParsingStrategy.GetNextParentNodeId();
|
var nextParentNodeId = await _layoutParsingStrategy.GetNextParentNodeId();
|
||||||
IRoom? parentRoomNode = null;
|
Room? parentRoomNode = null;
|
||||||
if (nextParentNodeId != null)
|
if (nextParentNodeId != null)
|
||||||
{
|
{
|
||||||
//If the new room has the parent's ID, then we pass the parent's room into the compute function.
|
//If the new room has the parent's ID, then we pass the parent's room into the compute function.
|
||||||
//如果新房间有父节点的ID,那么我们将父节点的房间传入到计算函数内。
|
//如果新房间有父节点的ID,那么我们将父节点的房间传入到计算函数内。
|
||||||
parentRoomNode = roomDictionary[nextParentNodeId];
|
if (roomDictionary.TryGetValue(nextParentNodeId, out var value))
|
||||||
|
{
|
||||||
|
parentRoomNode = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var roomPlacementData =
|
var roomPlacementData =
|
||||||
|
@ -106,7 +124,7 @@ public static class MapGenerator
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await _roomPlacementStrategy.PlaceRoom(roomPlacementData))
|
if (!await _roomPlacementStrategy.PlaceRoom(_mapRoot, roomPlacementData))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
using ColdMint.scripts.debug;
|
|
||||||
using ColdMint.scripts.map.interfaces;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
namespace ColdMint.scripts.map;
|
|
||||||
|
|
||||||
public class MapGeneratorConfig : IMapGeneratorConfig
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <para>At least how many rooms are generated</para>
|
|
||||||
/// <para>至少生成多少个房间</para>
|
|
||||||
/// </summary>
|
|
||||||
public const int MinRoomCount = 15;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Maximum number of rooms generated</para>
|
|
||||||
/// <para>最多生成多少个房间</para>
|
|
||||||
/// </summary>
|
|
||||||
public const int MaxRoomCount = 30;
|
|
||||||
|
|
||||||
|
|
||||||
public const int MinBranchCount = 3;
|
|
||||||
|
|
||||||
public const int MaxBranchCount = 5;
|
|
||||||
|
|
||||||
private int _roomCount;
|
|
||||||
private int _branchCount;
|
|
||||||
|
|
||||||
public MapGeneratorConfig(Node2D mapRoot, ulong seed)
|
|
||||||
{
|
|
||||||
MapRoot = mapRoot;
|
|
||||||
Seed = seed;
|
|
||||||
RandomNumberGenerator = new RandomNumberGenerator();
|
|
||||||
RandomNumberGenerator.Seed = seed;
|
|
||||||
_roomCount = RandomNumberGenerator.RandiRange(MinRoomCount, MaxRoomCount);
|
|
||||||
_branchCount = RandomNumberGenerator.RandiRange(MinBranchCount, MaxBranchCount);
|
|
||||||
LogCat.Log("Seed:" + seed + " RoomCount:" + _roomCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node2D MapRoot { get; }
|
|
||||||
public int RoomCount => _roomCount;
|
|
||||||
public int BranchCount => _branchCount;
|
|
||||||
|
|
||||||
public ulong Seed { get; }
|
|
||||||
public RandomNumberGenerator RandomNumberGenerator { get; }
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using ColdMint.scripts.map.interfaces;
|
|
||||||
using ColdMint.scripts.map.room;
|
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.RoomProvider;
|
|
||||||
|
|
||||||
public class RoomProvider : IRoomProvider
|
|
||||||
{
|
|
||||||
private List<RoomTemplate> _roomTemplates;
|
|
||||||
|
|
||||||
public RoomProvider()
|
|
||||||
{
|
|
||||||
_roomTemplates = new List<RoomTemplate>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>AddRoom</para>
|
|
||||||
/// <para>添加房间</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
///<para>If the initial room is not set, the first room added will be automatically set as the initial room</para>
|
|
||||||
///<para>若未设置初始房间,那么第一次添加的房间将被自动设置为初始房间</para>
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="roomTemplate"></param>
|
|
||||||
public void AddRoom(RoomTemplate roomTemplate)
|
|
||||||
{
|
|
||||||
if (InitialRoom == null)
|
|
||||||
{
|
|
||||||
InitialRoom = roomTemplate;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_roomTemplates.Add(roomTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public IRoomTemplate? InitialRoom { get; set; }
|
|
||||||
|
|
||||||
public IRoomTemplate GetRoomRes(int index, IMapGeneratorConfig config)
|
|
||||||
{
|
|
||||||
var indexInList = config.RandomNumberGenerator.RandiRange(0, _roomTemplates.Count - 1);
|
|
||||||
IRoomTemplate result = _roomTemplates[indexInList];
|
|
||||||
|
|
||||||
//添加一次使用次数,当模板不能再次使用时,从列表内移除。
|
|
||||||
result.AddUsedNumber();
|
|
||||||
if (!result.CanUse)
|
|
||||||
{
|
|
||||||
_roomTemplates.RemoveAt(indexInList);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
using ColdMint.scripts.map.interfaces;
|
using ColdMint.scripts.map.room;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.dateBean;
|
namespace ColdMint.scripts.map.dateBean;
|
||||||
|
@ -18,5 +18,5 @@ public class RoomPlacementData
|
||||||
/// <para>Place the room template</para>
|
/// <para>Place the room template</para>
|
||||||
/// <para>放置的房间模板</para>
|
/// <para>放置的房间模板</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IRoom? Room { get; set; }
|
public Room? Room { get; set; }
|
||||||
}
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
using Godot;
|
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.interfaces;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>IMapGeneratorConfig</para>
|
|
||||||
/// <para>房间生成器配置</para>
|
|
||||||
/// </summary>
|
|
||||||
public interface IMapGeneratorConfig
|
|
||||||
{
|
|
||||||
Node2D MapRoot { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>How many rooms do we need to generate</para>
|
|
||||||
/// <para>我们需要生成多少个房间</para>
|
|
||||||
/// </summary>
|
|
||||||
int RoomCount { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>The number of forks in this map</para>
|
|
||||||
/// <para>这个地图的分叉数量</para>
|
|
||||||
/// </summary>
|
|
||||||
int BranchCount { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>seed</para>
|
|
||||||
/// <para>种子</para>
|
|
||||||
/// </summary>
|
|
||||||
ulong Seed { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>RandomNumberGenerator</para>
|
|
||||||
/// <para>随机数生成器</para>
|
|
||||||
/// </summary>
|
|
||||||
RandomNumberGenerator RandomNumberGenerator { get; }
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
using ColdMint.scripts.map.dateBean;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.interfaces;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>IRoom</para>
|
|
||||||
/// <para>表示房间</para>
|
|
||||||
/// </summary>
|
|
||||||
public interface IRoom
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Set room scene</para>
|
|
||||||
/// <para>设置房间场景</para>
|
|
||||||
/// </summary>
|
|
||||||
PackedScene? RoomScene { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Tile map</para>
|
|
||||||
/// <para>瓦片地图</para>
|
|
||||||
/// </summary>
|
|
||||||
TileMap? TileMap { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Gets the root node of the room</para>
|
|
||||||
/// <para>获取房间的根节点</para>
|
|
||||||
/// </summary>
|
|
||||||
Node2D? RootNode { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>The room holds the corresponding slot data</para>
|
|
||||||
/// <para>房间持有对应的插槽数据</para>
|
|
||||||
/// </summary>
|
|
||||||
RoomSlot?[]? RoomSlots { get; }
|
|
||||||
}
|
|
|
@ -1,4 +1,6 @@
|
||||||
namespace ColdMint.scripts.map.interfaces;
|
using ColdMint.scripts.map.room;
|
||||||
|
|
||||||
|
namespace ColdMint.scripts.map.interfaces;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Room holder</para>
|
/// <para>Room holder</para>
|
||||||
|
@ -10,13 +12,13 @@
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public interface IRoomHolder
|
public interface IRoomHolder
|
||||||
{
|
{
|
||||||
bool AddRoom(IRoom room);
|
bool AddRoom(Room room);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>LastRoom</para>
|
/// <para>LastRoom</para>
|
||||||
/// <para>最后添加的房间</para>
|
/// <para>最后添加的房间</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IRoom? LastRoom { get; }
|
Room? LastRoom { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Number of rooms that have been placed</para>
|
/// <para>Number of rooms that have been placed</para>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ColdMint.scripts.levelGraphEditor;
|
using ColdMint.scripts.levelGraphEditor;
|
||||||
using ColdMint.scripts.map.dateBean;
|
using ColdMint.scripts.map.dateBean;
|
||||||
|
using ColdMint.scripts.map.room;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.interfaces;
|
namespace ColdMint.scripts.map.interfaces;
|
||||||
|
|
||||||
|
@ -10,19 +12,20 @@ namespace ColdMint.scripts.map.interfaces;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRoomPlacementStrategy
|
public interface IRoomPlacementStrategy
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Place the room in the designated location</para>
|
/// <para>Place the room in the designated location</para>
|
||||||
/// <para>在指定的位置放置房间</para>
|
/// <para>在指定的位置放置房间</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="roomPlacementData">
|
/// <param name="mapRoot"></param>
|
||||||
///<para>Room placement information</para>
|
/// <param name="roomPlacementData">
|
||||||
///<para>房间放置信息</para>
|
/// <para>Room placement information</para>
|
||||||
/// </param>
|
/// <para>房间放置信息</para>
|
||||||
/// <returns>
|
/// </param>
|
||||||
///<para>Placement success or not</para>
|
/// <returns>
|
||||||
///<para>是否放置成功</para>
|
/// <para>Placement success or not</para>
|
||||||
/// </returns>
|
/// <para>是否放置成功</para>
|
||||||
public Task<bool> PlaceRoom(RoomPlacementData roomPlacementData);
|
/// </returns>
|
||||||
|
public Task<bool> PlaceRoom(Node mapRoot, RoomPlacementData roomPlacementData);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Calculate new room placement information</para>
|
/// <para>Calculate new room placement information</para>
|
||||||
|
@ -37,5 +40,5 @@ public interface IRoomPlacementStrategy
|
||||||
///<para>欲放置的新房间数据</para>
|
///<para>欲放置的新房间数据</para>
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task<RoomPlacementData?> CalculateNewRoomPlacementData(IRoom? parentRoomNode, RoomNodeData newRoomNodeData);
|
public Task<RoomPlacementData?> CalculateNewRoomPlacementData(Room? parentRoomNode, RoomNodeData newRoomNodeData);
|
||||||
}
|
}
|
|
@ -1,28 +0,0 @@
|
||||||
namespace ColdMint.scripts.map.interfaces;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Room provider</para>
|
|
||||||
/// <para>房间提供者</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
///<para>Responsible for providing room templates for map generator.</para>
|
|
||||||
///<para>负责为地图生成器提供房间模板。</para>
|
|
||||||
/// </remarks>
|
|
||||||
public interface IRoomProvider
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Initial room</para>
|
|
||||||
/// <para>初始房间</para>
|
|
||||||
/// </summary>
|
|
||||||
IRoomTemplate? InitialRoom { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <para>Acquire room assets</para>
|
|
||||||
/// <para>获取房间资产</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="index"></param>
|
|
||||||
/// <param name="config"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
IRoomTemplate? GetRoomRes(int index, IMapGeneratorConfig config);
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ColdMint.scripts.map.dateBean;
|
using ColdMint.scripts.map.dateBean;
|
||||||
|
using ColdMint.scripts.map.room;
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.interfaces;
|
namespace ColdMint.scripts.map.interfaces;
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ public interface IRoomSlotsMatcher
|
||||||
/// <param name="mainRoom"></param>
|
/// <param name="mainRoom"></param>
|
||||||
/// <param name="newRoom"></param>
|
/// <param name="newRoom"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<bool> IsMatch(IRoom? mainRoom, IRoom newRoom);
|
Task<bool> IsMatch(Room? mainRoom, Room newRoom);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using ColdMint.scripts.debug;
|
using ColdMint.scripts.debug;
|
||||||
using ColdMint.scripts.map.dateBean;
|
using ColdMint.scripts.map.dateBean;
|
||||||
using ColdMint.scripts.map.interfaces;
|
|
||||||
using ColdMint.scripts.utils;
|
using ColdMint.scripts.utils;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
|
@ -16,7 +15,7 @@ namespace ColdMint.scripts.map.room;
|
||||||
///<para>The room template is like a jigsaw puzzle and participates in the map building process.</para>
|
///<para>The room template is like a jigsaw puzzle and participates in the map building process.</para>
|
||||||
///<para>房间模板就像一个拼图,参与到地图的构建过程中。</para>
|
///<para>房间模板就像一个拼图,参与到地图的构建过程中。</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class Room : IRoom
|
public class Room
|
||||||
{
|
{
|
||||||
private Node2D? _rootNode;
|
private Node2D? _rootNode;
|
||||||
private RoomSlot?[]? _roomSlots;
|
private RoomSlot?[]? _roomSlots;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using ColdMint.scripts.map.interfaces;
|
using System.Collections.Generic;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.room;
|
namespace ColdMint.scripts.map.room;
|
||||||
|
@ -9,14 +9,67 @@ namespace ColdMint.scripts.map.room;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class RoomFactory
|
public static class RoomFactory
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>A room template sets a path to a room resource</para>
|
||||||
|
/// <para>房间模板集转房间资源路径</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="roomTemplateSet"></param>
|
||||||
|
/// <returns>
|
||||||
|
/// <para>Returned value Checked for the existence of the file.</para>
|
||||||
|
/// <para>返回值已检验文件是否存在。</para>
|
||||||
|
/// </returns>
|
||||||
|
public static string[] RoomTemplateSetToRoomRes(string[] roomTemplateSet)
|
||||||
|
{
|
||||||
|
var resList = new List<string>();
|
||||||
|
foreach (var roomTemplate in roomTemplateSet)
|
||||||
|
{
|
||||||
|
//Detects whether it is a folder
|
||||||
|
//检测是否为文件夹
|
||||||
|
if (DirAccess.DirExistsAbsolute(roomTemplate))
|
||||||
|
{
|
||||||
|
using var dir = DirAccess.Open(roomTemplate);
|
||||||
|
if (dir != null)
|
||||||
|
{
|
||||||
|
dir.ListDirBegin();
|
||||||
|
var fileName = dir.GetNext();
|
||||||
|
while (!string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
if (!dir.CurrentIsDir())
|
||||||
|
{
|
||||||
|
resList.Add(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName = dir.GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileAccess.FileExists(roomTemplate))
|
||||||
|
{
|
||||||
|
resList.Add(roomTemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resList.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>CreateRoom</para>
|
/// <para>CreateRoom</para>
|
||||||
/// <para>创建房间模板</para>
|
/// <para>创建房间模板</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="resPath"></param>
|
/// <param name="resPath"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IRoom CreateRoom(string resPath)
|
public static Room? CreateRoom(string resPath)
|
||||||
{
|
{
|
||||||
|
//If the file does not exist, null is returned
|
||||||
|
//如果文件不存在,则返回null
|
||||||
|
var exists = FileAccess.FileExists(resPath);
|
||||||
|
if (!exists)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var room = new Room
|
var room = new Room
|
||||||
{
|
{
|
||||||
RoomScene = GD.Load<PackedScene>(resPath)
|
RoomScene = GD.Load<PackedScene>(resPath)
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using ColdMint.scripts.map.interfaces;
|
using ColdMint.scripts.map.interfaces;
|
||||||
|
using ColdMint.scripts.map.room;
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.roomHolder;
|
namespace ColdMint.scripts.map.roomHolder;
|
||||||
|
|
||||||
public class RoomHolder : IRoomHolder
|
public class RoomHolder : IRoomHolder
|
||||||
{
|
{
|
||||||
private readonly List<IRoom> _rooms = new List<IRoom>();
|
private readonly List<Room> _rooms = new List<Room>();
|
||||||
|
|
||||||
public bool AddRoom(IRoom room)
|
public bool AddRoom(Room room)
|
||||||
{
|
{
|
||||||
_rooms.Add(room);
|
_rooms.Add(room);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRoom? LastRoom
|
public Room? LastRoom
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using ColdMint.scripts.levelGraphEditor;
|
using ColdMint.scripts.levelGraphEditor;
|
||||||
using ColdMint.scripts.map.dateBean;
|
using ColdMint.scripts.map.dateBean;
|
||||||
using ColdMint.scripts.map.interfaces;
|
using ColdMint.scripts.map.interfaces;
|
||||||
|
using ColdMint.scripts.map.room;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.RoomPlacer;
|
namespace ColdMint.scripts.map.RoomPlacer;
|
||||||
|
@ -16,19 +17,88 @@ namespace ColdMint.scripts.map.RoomPlacer;
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class PatchworkRoomPlacementStrategy : IRoomPlacementStrategy
|
public class PatchworkRoomPlacementStrategy : IRoomPlacementStrategy
|
||||||
{
|
{
|
||||||
public Task<bool> PlaceRoom(RoomPlacementData roomPlacementData)
|
private readonly Vector2 _halfCell = new Vector2(Config.CellSize / 2f, Config.CellSize / 2f);
|
||||||
|
|
||||||
|
public Task<bool> PlaceRoom(Node mapRoot, RoomPlacementData roomPlacementData)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
if (roomPlacementData.Room == null || roomPlacementData.Position == null)
|
||||||
|
{
|
||||||
|
return Task.FromResult(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roomPlacementData.Room.RootNode == null)
|
||||||
|
{
|
||||||
|
return Task.FromResult(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootNode = roomPlacementData.Room.RootNode;
|
||||||
|
rootNode.Reparent(mapRoot);
|
||||||
|
rootNode.Position = roomPlacementData.Position.Value;
|
||||||
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<RoomPlacementData?> GetStartRoomPlacementData(RoomNodeData startRoomNodeData)
|
public Task<RoomPlacementData?> CalculateNewRoomPlacementData(Room? parentRoomNode, RoomNodeData newRoomNodeData)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
if (newRoomNodeData.RoomTemplateSet == null || newRoomNodeData.RoomTemplateSet.Length == 0)
|
||||||
|
{
|
||||||
|
return Task.FromResult<RoomPlacementData?>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var roomResArray = RoomFactory.RoomTemplateSetToRoomRes(newRoomNodeData.RoomTemplateSet);
|
||||||
|
if (parentRoomNode == null)
|
||||||
|
{
|
||||||
|
//No parent node is set, which we think is the starting room.
|
||||||
|
//没有设置父节点,我们认为是起点房间。
|
||||||
|
//TODO:在这里兼容世界种子。
|
||||||
|
var roomPlacementData = new RoomPlacementData
|
||||||
|
{
|
||||||
|
Room = RoomFactory.CreateRoom(roomResArray[0]),
|
||||||
|
Position = Vector2.Zero
|
||||||
|
};
|
||||||
|
return Task.FromResult<RoomPlacementData?>(roomPlacementData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//TODO:在这里实现房间的放置策略。
|
||||||
|
return Task.FromResult<RoomPlacementData?>(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Task<Vector2?> CalculatedPosition(Room mainRoom, Room newRoom, RoomSlot? mainRoomSlot,
|
||||||
public Task<RoomPlacementData?> CalculateNewRoomPlacementData(IRoom parentRoomNode, RoomNodeData newRoomNodeData)
|
RoomSlot? newRoomSlot,bool roomSlotOverlap)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
if (mainRoom.RootNode == null || mainRoom.TileMap == null || newRoom.TileMap == null || mainRoomSlot == null ||
|
||||||
|
newRoomSlot == null)
|
||||||
|
{
|
||||||
|
return Task.FromResult<Vector2?>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//计算主插槽中点在世界中的位置。
|
||||||
|
//mainRoom.RootNode.Position意为房间所在的世界位置
|
||||||
|
//mainRoom.TileMap.MapToLocal(mainRoomSlot.StartPosition)意为主插槽在房间中的位置
|
||||||
|
var result = mainRoom.RootNode.Position + mainRoom.TileMap.MapToLocal(mainRoomSlot.StartPosition);
|
||||||
|
if (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<Vector2?>(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ColdMint.scripts.map.dateBean;
|
using ColdMint.scripts.map.dateBean;
|
||||||
using ColdMint.scripts.map.interfaces;
|
using ColdMint.scripts.map.interfaces;
|
||||||
|
using ColdMint.scripts.map.room;
|
||||||
|
|
||||||
namespace ColdMint.scripts.map.slotsMatcher;
|
namespace ColdMint.scripts.map.slotsMatcher;
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ public class RoomSlotsMatcher : IRoomSlotsMatcher
|
||||||
private RoomSlot? _lastMatchedMainSlot;
|
private RoomSlot? _lastMatchedMainSlot;
|
||||||
private RoomSlot? _lastMatchedMinorSlot;
|
private RoomSlot? _lastMatchedMinorSlot;
|
||||||
|
|
||||||
public Task<bool> IsMatch(IRoom? mainRoom, IRoom newRoom)
|
public Task<bool> IsMatch(Room? mainRoom, Room newRoom)
|
||||||
{
|
{
|
||||||
if (mainRoom == null)
|
if (mainRoom == null)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user