// Fill out your copyright notice in the Description page of Project Settings. #include "Widgets/BagConfigGridWidget.h" #include "ProjectFish/DataAsset/BagShapeAsset.h" const float SBagConfigGridWidget::CellSize = 32.0f; const float SBagConfigGridWidget::CellSpacing = 2.0f; void SBagConfigGridWidget::Construct(const FArguments& InArgs) { BagConfig = InArgs._BagConfig; OnGridCellClicked = InArgs._OnGridCellClicked; PreviewSkill = nullptr; PreviewX = -1; PreviewY = -1; ChildSlot [ SNew(SOverlay) ]; } void SBagConfigGridWidget::RefreshGrid() { // 强制重绘 Invalidate(EInvalidateWidget::Paint); } FReply SBagConfigGridWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) { if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton && BagConfig.IsValid()) { FVector2D LocalPosition = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()); FVector2D GridCell = GetGridCellFromPosition(LocalPosition); int32 GridX = FMath::FloorToInt(GridCell.X); int32 GridY = FMath::FloorToInt(GridCell.Y); if (IsValidGridPosition(GridX, GridY)) { OnGridCellClicked.ExecuteIfBound(GridX, GridY); return FReply::Handled(); } } return FReply::Unhandled(); } FReply SBagConfigGridWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) { return FReply::Unhandled(); } int32 SBagConfigGridWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const { if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset) { return LayerId; } UBagShapeAsset* BagShapeAsset = BagConfig->BagShapeAsset; // 绘制背包格子 for (int32 Y = 0; Y < BagShapeAsset->BagHeight; Y++) { for (int32 X = 0; X < BagShapeAsset->BagWidth; X++) { FVector2D CellPos = GetCellPosition(X, Y); FVector2D CellSizeVec(CellSize, CellSize); // 获取格子颜色 FLinearColor CellColor = GetCellColor(X, Y); // 绘制格子背景 FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(CellSizeVec, FSlateLayoutTransform(CellPos)), FCoreStyle::Get().GetBrush("WhiteBrush"), ESlateDrawEffect::None, CellColor ); // 绘制格子边框 FSlateDrawElement::MakeBox( OutDrawElements, LayerId + 1, AllottedGeometry.ToPaintGeometry(CellSizeVec, FSlateLayoutTransform(CellPos)), FCoreStyle::Get().GetBrush("Border"), ESlateDrawEffect::None, FLinearColor::Black ); } } // 绘制已放置的技能 for (int32 i = 0; i < BagConfig->PlacedSkills.Num(); i++) { const FPlacedSkillInfo& PlacedSkill = BagConfig->PlacedSkills[i]; FVector2D SkillPos = GetCellPosition(PlacedSkill.PositionX, PlacedSkill.PositionY); FVector2D SkillSizeVec(GetSkillSizeValue(PlacedSkill.SkillAsset->SkillSize).X * (CellSize + CellSpacing) - CellSpacing, GetSkillSizeValue(PlacedSkill.SkillAsset->SkillSize).Y* (CellSize + CellSpacing) - CellSpacing); // 绘制技能背景 FSlateDrawElement::MakeBox( OutDrawElements, LayerId + 2, AllottedGeometry.ToPaintGeometry(SkillSizeVec, FSlateLayoutTransform(SkillPos)), FCoreStyle::Get().GetBrush("WhiteBrush"), ESlateDrawEffect::None, FLinearColor::Blue ); // 绘制技能边框 FSlateDrawElement::MakeBox( OutDrawElements, LayerId + 3, AllottedGeometry.ToPaintGeometry(SkillSizeVec, FSlateLayoutTransform(SkillPos)), FCoreStyle::Get().GetBrush("Border"), ESlateDrawEffect::None, FLinearColor::White ); // 绘制技能名称 if (!PlacedSkill.SkillAsset->SkillName.IsEmpty()) { FSlateDrawElement::MakeText( OutDrawElements, LayerId + 4, AllottedGeometry.ToPaintGeometry(SkillSizeVec, FSlateLayoutTransform(SkillPos + FVector2D(4, 4))), PlacedSkill.SkillAsset->SkillName, FCoreStyle::GetDefaultFontStyle("Regular", 10), ESlateDrawEffect::None, FLinearColor::White ); } } // 绘制预览技能 if (PreviewSkill.IsValid() && PreviewX >= 0 && PreviewY >= 0) { FVector2D PreviewPos = GetCellPosition(PreviewX, PreviewY); FVector2D PreviewSizeVec(GetSkillSizeValue(PreviewSkill->SkillSize).X * (CellSize + CellSpacing) - CellSpacing, GetSkillSizeValue(PreviewSkill->SkillSize).Y * (CellSize + CellSpacing) - CellSpacing); FLinearColor PreviewColor = FLinearColor::Blue; PreviewColor.A = 0.5f; // 半透明 // 绘制预览背景 FSlateDrawElement::MakeBox( OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(PreviewSizeVec, FSlateLayoutTransform(PreviewPos)), FCoreStyle::Get().GetBrush("WhiteBrush"), ESlateDrawEffect::None, PreviewColor ); // 绘制预览边框(虚线效果) FSlateDrawElement::MakeBox( OutDrawElements, LayerId + 6, AllottedGeometry.ToPaintGeometry(PreviewSizeVec, FSlateLayoutTransform(PreviewPos)), FCoreStyle::Get().GetBrush("Border"), ESlateDrawEffect::None, FLinearColor::Yellow ); } return LayerId + 7; } FVector2D SBagConfigGridWidget::ComputeDesiredSize(float X) const { if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset) { return FVector2D(100, 100); } UBagShapeAsset* BagShapeAsset = BagConfig->BagShapeAsset; return FVector2D( BagShapeAsset->BagWidth * (CellSize + CellSpacing) - CellSpacing, BagShapeAsset->BagHeight * (CellSize + CellSpacing) - CellSpacing ); } FVector2D SBagConfigGridWidget::GetGridCellFromPosition(const FVector2D& Position) const { return FVector2D( Position.X / (CellSize + CellSpacing), Position.Y / (CellSize + CellSpacing) ); } bool SBagConfigGridWidget::IsValidGridPosition(int32 X, int32 Y) const { if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset) { return false; } return X >= 0 && X < BagConfig->BagShapeAsset->BagWidth && Y >= 0 && Y < BagConfig->BagShapeAsset->BagHeight; } FLinearColor SBagConfigGridWidget::GetCellColor(int32 X, int32 Y) const { if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset) { return FLinearColor::Gray; } // 检查格子是否激活 if (!BagConfig->BagShapeAsset->IsSlotActive(X, Y)) { return FLinearColor(0.2f, 0.2f, 0.2f, 1.0f); // 非激活格子为深灰色 } // 检查是否被技能占用 int32 SkillIndex = BagConfig->GetSkillAtPosition(X, Y); if (SkillIndex >= 0) { return FLinearColor(0, 0, 1, 1); } // 空闲格子为浅灰色 return FLinearColor(0.7f, 0.7f, 0.7f, 1.0f); }