213 lines
6.8 KiB
C++
213 lines
6.8 KiB
C++
#include "FishingMapSystem.h"
|
||
#include "Engine/Engine.h"
|
||
|
||
UFishingMapNode::UFishingMapNode()
|
||
{
|
||
NodeID = FGuid::NewGuid();
|
||
|
||
NodeType = EMapNodeType::Battle;
|
||
LayerIndex = 0;
|
||
IndexInLayer = 0;
|
||
Position = FVector2D::ZeroVector;
|
||
}
|
||
|
||
void UFishingMapNode::RandomNodeType()
|
||
{
|
||
NodeType = static_cast<EMapNodeType>(FMath::RandRange(0, 1));
|
||
}
|
||
|
||
UFishingMapSystem::UFishingMapSystem()
|
||
{
|
||
|
||
}
|
||
|
||
void UFishingMapSystem::GenerateMap()
|
||
{
|
||
GenerateMapWithConfig(MapConfig);
|
||
}
|
||
|
||
void UFishingMapSystem::GenerateMapWithConfig(const UMapConfigAsset* Config)
|
||
{
|
||
// 清空现有数据
|
||
ClearMap();
|
||
|
||
// 生成节点
|
||
GenerateNodes();
|
||
|
||
// 计算节点位置
|
||
CalculateNodePositions();
|
||
|
||
// 生成连线
|
||
GenerateConnections();
|
||
|
||
UE_LOG(LogTemp, Log, TEXT("地图生成完成:%d层,共%d个节点,%d条连线"),
|
||
GetLayerCount(), AllNodes.Num(), AllConnections.Num());
|
||
}
|
||
|
||
int32 UFishingMapSystem::GetNodeAtLayerIndex(FGuid NodeID) const
|
||
{
|
||
for (FMapLayer Layer: AllLayers)
|
||
{
|
||
for (int i = 0; i < Layer.GetNodeNum(); i++)
|
||
{
|
||
if ( Layer.GetNode(i)->NodeID == NodeID)
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
void UFishingMapSystem::ClearMap()
|
||
{
|
||
AllNodes.Empty();
|
||
AllConnections.Empty();
|
||
AllLayers.Empty();
|
||
}
|
||
|
||
|
||
void UFishingMapSystem::GenerateNodes()
|
||
{
|
||
AllLayers.SetNum(MapConfig->TotalLayers);
|
||
|
||
for (int32 LayerIndex = 0; LayerIndex < MapConfig->TotalLayers ; ++LayerIndex)
|
||
{
|
||
if (LayerIndex == MapConfig->TotalLayers - 1)
|
||
{
|
||
//最后一层 只有一个Boss
|
||
UFishingMapNode* NewNode = NewObject<UFishingMapNode>(this);
|
||
NewNode->LayerIndex = LayerIndex;
|
||
NewNode->IndexInLayer = 0;
|
||
NewNode->NodeType = EMapNodeType::Boss;
|
||
AllNodes.Add(NewNode);
|
||
AllLayers[LayerIndex].AddNode(NewNode);
|
||
}
|
||
else
|
||
{
|
||
// 随机生成节点数量
|
||
int32 NodeCount = FMath::RandRange(MapConfig->Layer_MinNodes, MapConfig->Layer_MaxNodes);
|
||
// 生成节点
|
||
for (int32 NodeIndex = 0; NodeIndex < NodeCount; ++NodeIndex)
|
||
{
|
||
UFishingMapNode* NewNode = NewObject<UFishingMapNode>(this);
|
||
NewNode->LayerIndex = LayerIndex;
|
||
NewNode->IndexInLayer = NodeIndex;
|
||
|
||
// 随机节点类型
|
||
NewNode->RandomNodeType();
|
||
AllNodes.Add(NewNode);
|
||
AllLayers[LayerIndex].AddNode(NewNode);
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
void UFishingMapSystem::CalculateNodePositions()
|
||
{
|
||
// float LayerSpacing = 1000.0f; // 层之间的距离
|
||
// float NodeSpacing = 300.0f; // 节点之间的距离
|
||
//
|
||
// for (int32 LayerIndex = 0; LayerIndex < AllLayers.Num(); ++LayerIndex)
|
||
// {
|
||
// FMapLayer& Layer= AllLayers[LayerIndex];
|
||
// int32 NodeCount = Layer.GetNodeNum();
|
||
//
|
||
// float X = LayerIndex * LayerSpacing;
|
||
// float TotalWidth = (NodeCount - 1) * NodeSpacing;
|
||
// float StartY = -TotalWidth * 0.5f;
|
||
//
|
||
// for (int32 NodeIndex = 0; NodeIndex <NodeCount; ++NodeIndex)
|
||
// {
|
||
// if (LayerNodes[NodeIndex])
|
||
// {
|
||
// float Y = StartY + NodeIndex * NodeSpacing;
|
||
// LayerNodes[NodeIndex]->Position = FVector2D(X, Y);
|
||
// }
|
||
// }
|
||
// }
|
||
}
|
||
|
||
void UFishingMapSystem::GenerateConnections()
|
||
{
|
||
AllConnections.Empty();
|
||
|
||
// 为每对相邻层生成连线
|
||
for (int32 LayerIndex = 0; LayerIndex < AllLayers.Num() - 1; ++LayerIndex)
|
||
{
|
||
TArray<FSimpleConnection> LayerConnections = GenerateNonCrossingConnections(LayerIndex, LayerIndex + 1);
|
||
AllConnections.Append(LayerConnections);
|
||
}
|
||
|
||
// 更新节点的连接信息
|
||
for (const FSimpleConnection& Connection : AllConnections)
|
||
{
|
||
// 找到起始节点并添加连接
|
||
for (UFishingMapNode* Node : AllNodes)
|
||
{
|
||
if (Node && Node->NodeID == Connection.FromNodeID)
|
||
{
|
||
Node->ConnectedNodes.AddUnique(Connection.ToNodeID);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
TArray<FSimpleConnection> UFishingMapSystem::GenerateNonCrossingConnections(int32 FromLayer, int32 ToLayer)
|
||
{
|
||
TArray<FSimpleConnection> Connections;
|
||
|
||
if (FromLayer == AllLayers.Num() - 2)
|
||
{
|
||
//倒数第二行,所有都连接到最终boss房间
|
||
FMapLayer FromNodes = AllLayers[FromLayer];
|
||
FGuid BossID = AllLayers[ToLayer].GetNode(0)->NodeID;
|
||
for (int32 NodeIndex = 0; NodeIndex < FromNodes.GetNodeNum(); ++NodeIndex)
|
||
{
|
||
Connections.Add(FSimpleConnection(FromNodes.GetNode(NodeIndex)->NodeID, BossID));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//第一步 随机为每个fromnode 分配指定范围的上层节点
|
||
FMapLayer FromNodes = AllLayers[FromLayer];
|
||
FMapLayer ToNodes = AllLayers[ToLayer];
|
||
int32 LastToNodeIndex = 0;
|
||
for (int32 NodeIndex = 0; NodeIndex < FromNodes.GetNodeNum(); ++NodeIndex)
|
||
{
|
||
int32 connectionBeginIndex = LastToNodeIndex;
|
||
int32 endIndex = ToNodes.GetNodeNum() - 1;
|
||
//随机连线的最左侧位置,根据当前所在layer的index 调整概率
|
||
int32 connectionEndIndex = FMath::Max(connectionBeginIndex,
|
||
(FMath::RandRange(connectionBeginIndex, endIndex + (FromNodes.GetNodeNum() - NodeIndex)) - (FromNodes.GetNodeNum() - NodeIndex)) );
|
||
//随机指定当前node 连接上层node的范围
|
||
LastToNodeIndex = FMath::RandRange(connectionBeginIndex, connectionEndIndex);
|
||
for(int32 i = connectionEndIndex; i < connectionEndIndex; ++i)
|
||
{
|
||
//添加连线
|
||
Connections.Add(FSimpleConnection(FromNodes.GetNode(NodeIndex)->NodeID, ToNodes.GetNode(connectionEndIndex)->NodeID));
|
||
}
|
||
}
|
||
//第二步 确保tolayer 每个节点都有连接线,没有连接线的分配 指定范围内的下层节点
|
||
if(LastToNodeIndex != ToNodes.GetNodeNum() - 1)
|
||
{
|
||
//还有上层节点是没有被连线状态,都连接到下层的最后一个节点
|
||
for(int32 ToNodeIndex = LastToNodeIndex; ToNodeIndex < ToNodes.GetNodeNum(); ++ToNodeIndex)
|
||
{
|
||
Connections.Add(FSimpleConnection(FromNodes.GetNode(FromNodes.GetNodeNum() - 1)->NodeID, ToNodes.GetNode(ToNodeIndex)->NodeID));
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
UE_LOG(LogTemp, Log, TEXT("生成层级 %d -> %d 的随机连接"),FromLayer, ToLayer);
|
||
for(auto connection: Connections)
|
||
{
|
||
UE_LOG(LogTemp, Log, TEXT("下层 %d -> 上层 %d "),GetNodeAtLayerIndex(connection.FromNodeID),
|
||
GetNodeAtLayerIndex(connection.FromNodeID));
|
||
}
|
||
|
||
|
||
return Connections;
|
||
}
|