320 lines
12 KiB
Lua
Raw Permalink Normal View History

2025-01-04 23:00:19 +08:00
---@class WB_CountingHeart_C:UUserWidget
---@field Button_AddCount UButton
---@field CanvasPanel_Map UCanvasPanel
---@field TextBlock_Count UTextBlock
---@field TextBlock_Time UTextBlock
---@field VerticalBox_CountingNum UVerticalBox
---@field WB_AllPlayerMiniScore UWB_AllPlayerMiniScore_C
---@field ShapeWidgetClass UClass
--Edit Below--
local WB_CountingHeart = {
bInitDoOnce = false;
StartGame = false;
MaxCount = 0;
CountingHeartTable = {};
AllShapeWidget = {};
-- 移动形状的列表 ID = TargetPos(2D) 其中ID为AllShapeWidget的索引
MoveList = {};
NowLevel = 1;
PlayerCountingNum = 0;
StartAddCountTime = 0;
StopAddCountTime = 0;
-- 正在显示心形的数量
bHeartCountShowing = false;
-- 移动速度
ShapeMoveSpeed = 0.3;
-- 当前回合的心形widget
HeartShapeList = {};
AllPlayerKey = {};
ShowHeartCountInterval = 0.2;
};
function WB_CountingHeart:Construct()
self:InitParam()
end
function WB_CountingHeart:OnShowPanel()
self.bIsShow = true
--local MainControlPanel = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C")
--MainControlPanel:SetVisibility(ESlateVisibility.Collapsed)
MiniGameConfig.ClientSetIsUIGame(true)
end
function WB_CountingHeart:OnClosePanel()
self.bIsShow = false
--local MainControlPanel = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C")
--MainControlPanel:SetVisibility(ESlateVisibility.SelfHitTestInvisible)
MiniGameConfig.ClientSetIsUIGame(false)
WidgetManager:ShowPanel(WidgetConfig.EUIType.UIGameBG, false)
end
function WB_CountingHeart:InitParam()
if self.bInitDoOnce then
return
end
self.bInitDoOnce = true
self.WB_AllPlayerMiniScore:Init()
UGCEventSystem.AddListener(EventEnum.UpdateShapeInfo, self.UpdateShapeInfo, self)
UGCEventSystem.AddListener(EventEnum.AddShapeMoveInfo, self.AddMoveInfo, self)
UGCEventSystem.AddListener(EventEnum.ClientSyncCountingNum, self.SyncCountingNum, self)
WidgetLibrary.BindButtonClicked(self.Button_AddCount, self.AddCount, self)
self.ShowHeartCountInterval = MiniGameConfig.MiniGameInfo[MiniGameConfig.MiniGameType.CountingHeartShaped].GameParam.ShowHeartCountInterval
local ParamTablePath = MiniGameConfig.MiniGameInfo[MiniGameConfig.MiniGameType.CountingHeartShaped].GameParam.ParamTable
self.CountingHeartTable = UGCSystemLibrary.GetDataTableFromPath(ParamTablePath, true)
-- 设置最大Item数量
for i, v in pairs(self.CountingHeartTable) do
self.MaxCount = math.max(v.HeartCountMax + v.ConfoundCountMax, self.MaxCount)
end
self:UpdateAllShapeWidget()
end
function WB_CountingHeart:UpdateAllShapeWidget()
for i = #self.AllShapeWidget + 1, self.MaxCount do
local ShapeItem = UserWidget.NewWidgetObjectBP(UGCSystemLibrary.GetLocalPlayerController(), self.ShapeWidgetClass);
self.CanvasPanel_Map:AddChild(ShapeItem)
ShapeItem:SetVisibility(ESlateVisibility.Collapsed)
self.AllShapeWidget[#self.AllShapeWidget + 1] = ShapeItem
end
end
function WB_CountingHeart:GetMapSize()
--if self.MapSize == nil or self.MapSize.X == 0 or self.MapSize.Y == 0 then
-- -- local CanvasSlot = WidgetLayoutLibrary.SlotAsCanvasSlot(self.CanvasPanel_Map);
-- -- self.MapSize = CanvasSlot:GetSize()
-- self.MapSize = SlateBlueprintLibrary.GetLocalSize(self.CanvasPanel_Map:GetCachedGeometry())
--end
return SlateBlueprintLibrary.GetLocalSize(self.CanvasPanel_Map:GetCachedGeometry())
end
function WB_CountingHeart:Tick(MyGeometry, InDeltaTime)
if self.bIsShow and self.StartGame then
self:UpdateMove(InDeltaTime)
local ServerTime = UGCGameSystem.GameState:GetServerGameTime()
if ServerTime >= self.StopAddCountTime then
self:ShowHeartCount()
end
local ShowTime = math.floor(self.StopAddCountTime - ServerTime)
if ShowTime > 0 then
self.TextBlock_Time:SetText(tostring(ShowTime))
else
self.TextBlock_Time:SetText("0")
end
end
end
---@param MoveInfos table:{{ID:int, TargetPos:Vector2D}, ...}
function WB_CountingHeart:AddMoveInfo(MoveInfos)
local TempMapSize = self:GetMapSize()
for _, Info in pairs(MoveInfos) do
local TempTargetPos = VectorHelper.Mul2D(Info.TargetPos, TempMapSize)
local InMoveList = false
for i, v in pairs(self.MoveList) do
if v.ID == Info.ID then
InMoveList = true
self.MoveList[i].TargetPos = TempTargetPos
break
end
end
if not InMoveList then
self.MoveList[#self.MoveList + 1] = {ID = Info.ID, TargetPos = TempTargetPos}
self.AllShapeWidget[Info.ID]:SetMoving()
end
end
UGCLogSystem.LogTree("[WB_CountingHeart_AddMoveInfo] MoveList:", self.MoveList)
end
function WB_CountingHeart:ClearMoveList()
self.MoveList = {}
end
function WB_CountingHeart:UpdateMove(DeltaTime)
if #self.MoveList > 0 then
-- .RenderTransform.Translation
-- SetRenderTranslation
for i = #self.MoveList, 1, -1 do
local Item = self.AllShapeWidget[self.MoveList[i].ID]
if Item then
-- local Pos = Item.RenderTransform.Translation
local ItemSlot = WidgetLayoutLibrary.SlotAsCanvasSlot(Item)
local Pos = ItemSlot:GetPosition();
local TargetPos = self.MoveList[i].TargetPos
local NewPos = KismetMathLibrary.Vector2DInterpTo(Pos, TargetPos, DeltaTime, self.ShapeMoveSpeed)
-- Item:SetRenderTranslation(NewPos)
ItemSlot:SetPosition(NewPos);
if KismetMathLibrary.EqualEqual_Vector2DVector2D(NewPos, TargetPos, 1e-3) then
self.AllShapeWidget[self.MoveList[i].ID] = nil
Item:StopMove()
end
else
self.AllShapeWidget[self.MoveList[i].ID] = nil
end
end
end
end
---@param ShapeInfo table:{{IsHeart:bool, Shape:int, Color:int, Pos:Vector2D}, ...}
function WB_CountingHeart:UpdateShapeInfo(Level, InStartAddCountTime, InStopAddCountTime, ShapeInfos)
-- 设置当前回合的参数
self.NowLevel = Level
self.StartAddCountTime = InStartAddCountTime
self.StopAddCountTime = InStopAddCountTime
-- 重置一些参数
self.PlayerCountingNum = 0
self:ClearMoveList()
self.TextBlock_Count:SetText("0")
self.bHeartCountShowing = false
self.HeartShapeList = {}
self.StartGame = true
UGCLogSystem.LogTree("[WB_CountingHeart_UpdateShapeInfo]ShapeInfos:", ShapeInfos)
local Size = self:GetMapSize()
UGCLogSystem.Log("[WB_CountingHeart_UpdateShapeInfo] Size:%s", VectorHelper.ToString2D(Size))
for i, Item in pairs(self.AllShapeWidget) do
local ShapeInfo = ShapeInfos[i]
if ShapeInfo then
local Tex = self:GetShapeTex(ShapeInfo.IsHeart, ShapeInfo.Shape)
local Color = self:GetShapeColor(ShapeInfo.IsHeart, ShapeInfo.Color)
if UE.IsValid(Tex) then
Item:SetTexture(Tex)
end
if Color then
Item:SetColor(Color)
end
Item:SetVisibility(ESlateVisibility.SelfHitTestInvisible)
Item:ShowCountText(false)
Item:SetIsHeart(ShapeInfo.IsHeart)
local Pos = KismetMathLibrary.Multiply_Vector2DVector2D(Size, ShapeInfo.Pos)
-- UGCLogSystem.Log("[WB_CountingHeart_UpdateShapeInfo] Pos%s", VectorHelper.ToString2D(Pos))
-- Item:SetRenderTranslation(Pos)
local ItemSlot = WidgetLayoutLibrary.SlotAsCanvasSlot(Item)
ItemSlot:SetPosition(Pos);
if ShapeInfo.IsHeart then
self.HeartShapeList[#self.HeartShapeList + 1] = Item
end
-- UGCLogSystem.Log("[WB_CountingHeart_UpdateShapeInfo] i:%s", tostring(i))
else
Item:SetVisibility(ESlateVisibility.Collapsed)
Item:SetIsHeart(false)
end
end
end
function WB_CountingHeart:GetShapeTex(IsHeart, ShapeID)
if self.CountingHeartTable[self.NowLevel] == nil then
return nil
end
if IsHeart then
return self.CountingHeartTable[self.NowLevel].HeartTextures[ShapeID]
else
return self.CountingHeartTable[self.NowLevel].ConfoundTextures[ShapeID]
end
end
function WB_CountingHeart:GetShapeColor(IsHeart, ColorID)
if self.CountingHeartTable[self.NowLevel] == nil then
return nil
end
if IsHeart then
return self.CountingHeartTable[self.NowLevel].HeartColors[ColorID]
else
return self.CountingHeartTable[self.NowLevel].ConfoundColors[ColorID]
end
end
function WB_CountingHeart:AddCount()
local NowServerTime = UGCGameSystem.GameState:GetServerGameTime()
if NowServerTime > self.StartAddCountTime and NowServerTime < self.StopAddCountTime then
self.PlayerCountingNum = self.PlayerCountingNum + 1
self.TextBlock_Count:SetText(tostring(self.PlayerCountingNum))
UGCSendRPCSystem.RPCEvent(nil, EventEnum.PlayerUpdateCountingNum, UGCSystemLibrary.GetLocalPlayerKey(), self.NowLevel, self.PlayerCountingNum)
SoundSystem.PlaySound(SoundSystem.ESound.Clock)
end
end
function WB_CountingHeart:ShowHeartCount()
self.StartGame = false
self.bHeartCountShowing = true
UGCLogSystem.Log("[WB_CountingHeart_ShowHeartCount]")
for i, v in pairs(self.MoveList) do
self.AllShapeWidget[v.ID]:StopMove()
end
table.sort(self.HeartShapeList, function(a, b)
local aItemSlot = WidgetLayoutLibrary.SlotAsCanvasSlot(a)
local aPos = aItemSlot:GetPosition();
local bItemSlot = WidgetLayoutLibrary.SlotAsCanvasSlot(b)
local bPos = bItemSlot:GetPosition();
if aPos.Y ~= bPos.Y then
return aPos.Y < bPos.Y
else
return aPos.X < bPos.X
end
end)
local ShowIndex = 1
if self.ShowHeartCountHandle == nil then
self.ShowHeartCountHandle = UGCEventSystem.SetTimerLoop(
self,
function()
if ShowIndex >= #self.HeartShapeList or self.bHeartCountShowing == false then
UGCEventSystem.StopTimer(self.ShowHeartCountHandle)
self.ShowHeartCountHandle = nil
end
if self.bHeartCountShowing then
local Item = self.HeartShapeList[ShowIndex]
if Item then
Item:SetCount(ShowIndex)
Item:ShowCountText(true)
SoundSystem.PlaySound(SoundSystem.ESound.Point)
end
ShowIndex = ShowIndex + 1
end
end,
self.ShowHeartCountInterval
)
end
end
function WB_CountingHeart:UpdateCountingNumPlayerKeys(InAllPlayerKey)
self.AllPlayerKey = InAllPlayerKey
UGCLogSystem.LogTree("[WB_AllPlayerMiniScore_UpdatePlayerKeys] AllPlayerKey", self.AllPlayerKey)
for i = 1, self.VerticalBox_CountingNum:GetChildrenCount() do
local Item = self.VerticalBox_CountingNum:GetChildAt(i - 1)
Item:SetPlayerKey(self.AllPlayerKey[i])
end
end
function WB_CountingHeart:SyncCountingNum(AllPlayerCountingNum)
UGCLogSystem.LogTree("[WB_CountingHeart_SyncCountingNum]AllPlayerCountingNum:", AllPlayerCountingNum)
if #self.AllPlayerKey ~= table.getCount(AllPlayerCountingNum) then
self:UpdateCountingNumPlayerKeys(table.getKeys(AllPlayerCountingNum))
end
for i = 1, self.VerticalBox_CountingNum:GetChildrenCount() do
local Item = self.VerticalBox_CountingNum:GetChildAt(i - 1)
if AllPlayerCountingNum[Item:GetPlayerKey()] then
Item:UpdatePlayerScore(AllPlayerCountingNum[Item:GetPlayerKey()])
end
end
end
return WB_CountingHeart;