---@class BP_CountingHeartManager_C:AActor ---@field DefaultSceneRoot USceneComponent --Edit Below-- local BP_CountingHeartManager = { bPlaying = false; MapRow = 10; MapCol = 17; MapCoordinate = {}; CoordinateIndex = 0; StopAddCountingTime = 0; CountingHeartTable = {}; ShowHeartCountInterval = 0.2; Level = 0; NowLevelHeartNum = 0; NowLevelConfoundCount = 0; NowLevelMobileFrequency = 0; ShapePosList = {}; StartAddCountTime = 0; StopAddCountTime = 0; PlayerCountingNum = {}; PlayerCountingNumIsChange = false; LastUpdatePlayerCountingNumTime = 0; UpdatePlayerCountingNumTimeInterval = 0.3; LastAddMoveValue = 0; LastNotifyAddMoveTime = 0; NotifyAddMoveTimeInterval = 0.4; }; function BP_CountingHeartManager:ReceiveBeginPlay() self.SuperClass.ReceiveBeginPlay(self); if UGCGameSystem.IsServer() then self:InitParam() UGCEventSystem.AddListener(EventEnum.PlayerUpdateCountingNum, self.PlayerUpdateCountingNum, self) end end function BP_CountingHeartManager:InitParam() local ParamTablePath = MiniGameConfig.MiniGameInfo[MiniGameConfig.MiniGameType.CountingHeartShaped].GameParam.ParamTable local CountingHeartAssetTable = TableHelper.CopyTable(UGCSystemLibrary.GetDataTableFromPath(ParamTablePath, true)) self.ShowHeartCountInterval = MiniGameConfig.MiniGameInfo[MiniGameConfig.MiniGameType.CountingHeartShaped].GameParam.ShowHeartCountInterval UGCLogSystem.LogTree("[BP_CountingHeartManager_InitParam] CountingHeartAssetTable:", CountingHeartAssetTable) for i = 0, self.MapCol do for j = 0, self.MapRow do self.MapCoordinate[#self.MapCoordinate + 1] = {X = i, Y = j} end end for i, LevelGameInfo in pairs(CountingHeartAssetTable) do self.CountingHeartTable[i] = {} self.CountingHeartTable[i].HeartCount = math.random(LevelGameInfo.HeartCountMin, LevelGameInfo.HeartCountMax) self.CountingHeartTable[i].ConfoundCount = math.random(LevelGameInfo.ConfoundCountMin, LevelGameInfo.ConfoundCountMax) self.CountingHeartTable[i].HeartTexCount = LevelGameInfo.HeartTextures:Num() self.CountingHeartTable[i].ConfoundTexCount = LevelGameInfo.ConfoundTextures:Num() self.CountingHeartTable[i].HeartShapeColorCount = LevelGameInfo.HeartColors:Num() self.CountingHeartTable[i].ConfoundShapeColorCount = LevelGameInfo.ConfoundColors:Num() self.CountingHeartTable[i].ShowTime = LevelGameInfo.ShowTime self.CountingHeartTable[i].MobileFrequency = LevelGameInfo.MobileFrequency self.CountingHeartTable[i].ShowCountTime = self.ShowHeartCountInterval * self.CountingHeartTable[i].HeartCount + 2 end UGCLogSystem.LogTree("[BP_CountingHeartManager_InitParam]", self.CountingHeartTable) end function BP_CountingHeartManager:GameStart() self:UpdateNewLevel() self.bPlaying = true end function BP_CountingHeartManager:StopGame() self.bPlaying = false end function BP_CountingHeartManager:PlayerUpdateCountingNum(PlayerKey, InLevel, CountingNum) if InLevel ~= self.Level then return end if self.PlayerCountingNum[PlayerKey] then self.PlayerCountingNum[PlayerKey] = math.max(self.PlayerCountingNum[PlayerKey], CountingNum) else self.PlayerCountingNum[PlayerKey] = math.max(0, CountingNum) end self.PlayerCountingNumIsChange = true end function BP_CountingHeartManager:ResetPlayerCountingNum() local AllPC = UGCGameSystem.GetAllPlayerController() self.PlayerCountingNum = {} for i, v in pairs(AllPC) do self.PlayerCountingNum[v.PlayerKey] = 0 end self.PlayerCountingNumIsChange = true end function BP_CountingHeartManager:UpdateNewLevel() self.Level = self.Level + 1 self.LastAddMoveValue = 0 self.LastNotifyAddMoveTime = 0 local LevelGameInfo = self.CountingHeartTable[self.Level] self:ResetPlayerCountingNum() if LevelGameInfo then UGCGameSystem.GameState:SetMiniGameInternalRound(self.Level) self:ResetShapePosList() --{IsHeart:bool, Shape:int, Color:int, Pos:Vector2D} local ShapeInfos = {} self.NowLevelHeartNum = LevelGameInfo.HeartCount self.NowLevelConfoundCount = LevelGameInfo.ConfoundCount self.NowLevelMobileFrequency = LevelGameInfo.MobileFrequency for i = 1, LevelGameInfo.HeartCount do ShapeInfos[#ShapeInfos + 1] = { IsHeart = true, Shape = math.random(1, LevelGameInfo.HeartTexCount), Color = math.random(1, LevelGameInfo.HeartShapeColorCount), Pos = self:GetNewPos2D(), } end for i = 1, LevelGameInfo.ConfoundCount do ShapeInfos[#ShapeInfos + 1] = { IsHeart = false, Shape = math.random(1, LevelGameInfo.ConfoundTexCount), Color = math.random(1, LevelGameInfo.ConfoundShapeColorCount), Pos = self:GetNewPos2D(), } end UGCLogSystem.LogTree("[BP_CountingHeartManager_UpdateNewLevel]ShapeInfos:", ShapeInfos) local ServerTime = UGCGameSystem.GameState:GetServerGameTime() self.StopAddCountingTime = ServerTime + LevelGameInfo.ShowTime UGCSendRPCSystem.RPCEvent(nil, EventEnum.UpdateShapeInfo, self.Level, ServerTime, self.StopAddCountingTime, ShapeInfos) UGCEventSystem.SetTimer(self, self.PlayerAddCountingScore, LevelGameInfo.ShowTime + 0.5) UGCEventSystem.SetTimer(self, self.UpdateNewLevel, LevelGameInfo.ShowTime + LevelGameInfo.ShowCountTime) return true else -- 发送结束信息 UGCEventSystem.SendEvent(EventEnum.MiniGameEndNotify) -- UGCLogSystem.LogError("[BP_CountingHeartManager_UpdateNewLevel] CountingHeartTable[%s] is nil", tostring(self.Level)) return false end end function BP_CountingHeartManager:PlayerAddCountingScore() local PlayerScoreInfo = {} for i, v in pairs(self.PlayerCountingNum) do PlayerScoreInfo[#PlayerScoreInfo + 1] = {PlayerKey = i, Score = math.abs(self.NowLevelHeartNum - v)} end table.sort(PlayerScoreInfo, function(a, b) return a.Score < b.Score end) local LastScore = nil local LastAddScore = 4 local PlayerAddScore = {} for i, v in pairs(PlayerScoreInfo) do if v.Score == LastScore then PlayerAddScore[v.PlayerKey] = LastAddScore else LastAddScore = 5 - i PlayerAddScore[v.PlayerKey] = LastAddScore LastScore = v.Score end end local AllPC = UGCGameSystem.GetAllPlayerController() for i, v in pairs(AllPC) do if PlayerAddScore[v.PlayerKey] == nil then PlayerAddScore[v.PlayerKey] = 1 end UGCGameSystem.GameState:PlayerAddMiniGameScore(v.PlayerKey, PlayerAddScore[v.PlayerKey]) MiniGameConfig.CheckPlayerTask(v.PlayerKey, MiniGameConfig.MiniGameType.CountingHeartShaped, UGCGameSystem.GameState:GetPlayerMiniGameScore(v.PlayerKey), false) end -- UGCEventSystem.SendEvent(EventEnum.AddMiniGameScoreList, PlayerAddScore) end --- 返回XY的范围均为[0,1]的向量 function BP_CountingHeartManager:GetNewPos2D() -- 区间分隔逻辑 self.CoordinateIndex = self.CoordinateIndex + 1 return {X = self.MapCoordinate[self.CoordinateIndex].X / self.MapCol, Y = self.MapCoordinate[self.CoordinateIndex].Y / self.MapRow} -- 测试逻辑 -- return {X = KismetMathLibrary.RandomFloat(), Y = KismetMathLibrary.RandomFloat()} end --- 获取一个移动的位置 function BP_CountingHeartManager:GetShapeMovePos() -- 测试逻辑 return {X = KismetMathLibrary.RandomFloat(), Y = KismetMathLibrary.RandomFloat()} end function BP_CountingHeartManager:ResetShapePosList() self.ShapePosList = {} self.CoordinateIndex = 0; table.Shuffle(self.MapCoordinate) end function BP_CountingHeartManager:NotifyAddMoveShape(Num) local AddMove = {} for i = 1, Num do AddMove[i] = {ID = math.random(1, self.NowLevelHeartNum + self.NowLevelConfoundCount), TargetPos = self:GetNewPos2D()} end UGCLogSystem.LogTree("[BP_CountingHeartManager_NotifyAddMoveShape]AddMove:", AddMove) UGCSendRPCSystem.RPCEvent(nil, EventEnum.AddShapeMoveInfo, AddMove) end function BP_CountingHeartManager:ReceiveTick(DeltaTime) self.SuperClass.ReceiveTick(self, DeltaTime); if UGCGameSystem.IsServer() and self.bPlaying then -- 延迟同步玩家数的计数 self.LastUpdatePlayerCountingNumTime = self.LastUpdatePlayerCountingNumTime + DeltaTime if self.PlayerCountingNumIsChange then if self.LastUpdatePlayerCountingNumTime > self.UpdatePlayerCountingNumTimeInterval then self.PlayerCountingNumIsChange = false self.LastUpdatePlayerCountingNumTime = 0 UGCSendRPCSystem.RPCEvent(nil, EventEnum.ClientSyncCountingNum, self.PlayerCountingNum) end end -- 更新形状UI移动 local ServerTime = UGCGameSystem.GameState:GetServerGameTime() if ServerTime < self.StopAddCountingTime then self.LastAddMoveValue = self.LastAddMoveValue + self.NowLevelMobileFrequency * DeltaTime self.LastNotifyAddMoveTime = self.NowLevelMobileFrequency + DeltaTime -- 判断是否满足1个以上的可移动数及是否满足发送RPC的时间 if self.LastAddMoveValue > 1 and self.LastNotifyAddMoveTime > self.NotifyAddMoveTimeInterval then self.LastNotifyAddMoveTime = self.LastNotifyAddMoveTime - self.NotifyAddMoveTimeInterval self:NotifyAddMoveShape(math.floor(self.LastAddMoveValue)) self.LastAddMoveValue = self.LastAddMoveValue % 1 end end else end end --[[ function BP_CountingHeartManager:ReceiveEndPlay() self.SuperClass.ReceiveEndPlay(self); end --]] --[[ function BP_CountingHeartManager:GetReplicatedProperties() return end --]] --[[ function BP_CountingHeartManager:GetAvailableServerRPCs() return end --]] return BP_CountingHeartManager;