From 19ca9f721233cbdbdcee558ccd1d3cb189b230ee Mon Sep 17 00:00:00 2001 From: 997146918 <997146918@qq.com> Date: Sun, 31 Aug 2025 15:49:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=83=8C=E5=8C=85=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=B8=AD=E7=9A=84=E8=83=8C=E5=8C=85=E9=A2=84=E8=A7=88?= =?UTF-8?q?UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Private/Widgets/BagConfigGridWidget.cpp | 220 ++++++++++++++++++ .../Public/Widgets/BagConfigGridWidget.h | 36 +-- 2 files changed, 243 insertions(+), 13 deletions(-) diff --git a/ProjectFish/Source/ProjectFishEditor/Private/Widgets/BagConfigGridWidget.cpp b/ProjectFish/Source/ProjectFishEditor/Private/Widgets/BagConfigGridWidget.cpp index b6c458e..ff845ac 100644 --- a/ProjectFish/Source/ProjectFishEditor/Private/Widgets/BagConfigGridWidget.cpp +++ b/ProjectFish/Source/ProjectFishEditor/Private/Widgets/BagConfigGridWidget.cpp @@ -3,12 +3,232 @@ #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); } diff --git a/ProjectFish/Source/ProjectFishEditor/Public/Widgets/BagConfigGridWidget.h b/ProjectFish/Source/ProjectFishEditor/Public/Widgets/BagConfigGridWidget.h index 1dff9b9..2ba04ad 100644 --- a/ProjectFish/Source/ProjectFishEditor/Public/Widgets/BagConfigGridWidget.h +++ b/ProjectFish/Source/ProjectFishEditor/Public/Widgets/BagConfigGridWidget.h @@ -32,17 +32,17 @@ SLATE_END_ARGS() void RefreshGrid(); protected: - // // Slate重写函数 - // virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - // virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - // virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, - // FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override; - // - // virtual FVector2D ComputeDesiredSize(float) const override; + // Slate重写函数 + virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; + virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; + virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, + FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override; + + virtual FVector2D ComputeDesiredSize(float) const override; private: // 背包类引用 - TWeakObjectPtr BagClass; + TWeakObjectPtr BagConfig; // 回调委托 FOnGridCellClicked OnGridCellClicked; @@ -56,10 +56,20 @@ private: static const float CellSize; static const float CellSpacing; - // // 工具函数 - // FVector2D GetCellPosition(int32 X, int32 Y) const; - // FVector2D GetGridCellFromPosition(const FVector2D& Position) const; - // bool IsValidGridPosition(int32 X, int32 Y) const; - // FLinearColor GetCellColor(int32 X, int32 Y) const; + // 工具函数 + FVector2D GetCellPosition(int32 X, int32 Y) const; + FVector2D GetGridCellFromPosition(const FVector2D& Position) const; + bool IsValidGridPosition(int32 X, int32 Y) const; + FLinearColor GetCellColor(int32 X, int32 Y) const; // int32 GetSkillAtPosition(int32 X, int32 Y) const; }; + +inline FVector2D SBagConfigGridWidget::GetCellPosition(int32 X, int32 Y) const +{ + return FVector2D( + X * (CellSize + CellSpacing), + Y * (CellSize + CellSpacing) + ); +} + +