local BattleUI = class("BattleUI", BaseUI) local GRID_CELL = "app/ui/battle/cell/grid_cell" local GRID_CELL_PATH = "assets/prefabs/ui/battle/cell/grid_cell.prefab" local SKILL_NODE_CELL = "app/ui/battle/cell/skill_node_cell" local DEFAULT_X = 10000 function BattleUI:getPrefabPath() return "assets/prefabs/ui/battle/battle_ui.prefab" end function BattleUI:onClose() self:clear() end function BattleUI:onLoadRootComplete() self:_display() self:_addListeners() self:_bind() end function BattleUI:_display() local uiMap = self.root:genAllChildren() self.uiMap = uiMap self.boardNode = uiMap["battle_ui.bg_2.board_node"] self.boardMask2D = self.boardNode:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_RECT_MASK_2D) self.boardMask = uiMap["battle_ui.bg_2.board_mask"] self.boardMask:setVisible(false) self.boardCacheNode = uiMap["battle_ui.bg_2.board_cache_node"] self.boardCacheNode:setVisible(false) self.boardCacheBox = uiMap["battle_ui.bg_2.board_cache_node.skill_box"] self:initSkill() self:initBattlefield() self:initNumberNode() self:initHpNode() self:hideGenerateSkillGridCells() end function BattleUI:_addListeners() local uiMap = self.root:genAllChildren() uiMap["battle_ui.close_btn"]:addClickListener(function() ModuleManager.BattleManager:showPauseUI() end) end function BattleUI:_bind() self:bind(DataManager.BattleData, "lvDirty", function() self:refreshLv() end, true) end function BattleUI:initSkill() if self.skillNodeCells then return end self.skillNodeCells = {} local uiMap = self.root:genAllChildren() for name, elementType in pairs(GConst.BattleConst.ELEMENT_TYPE) do self.skillNodeCells[elementType] = CellManager:addCellComp(uiMap["battle_ui.bg_2.skill_node_cell_" .. elementType], SKILL_NODE_CELL) local skillEntity = DataManager.BattleData:getSkillEntities()[elementType] if skillEntity then self.skillNodeCells[elementType]:refresh(skillEntity) end self.skillNodeCells[elementType]:getBaseObject():setActive(skillEntity ~= nil) end uiMap["battle_ui.bg_2.skill_node"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_HORIZONTAL_OR_VERTICAL_LAYOUT):RefreshLayout() end function BattleUI:initBattlefield() self.battleNode = self.uiMap["battle_ui.battle_node"] end function BattleUI:getBattleNode() return self.battleNode end function BattleUI:initNumberNode() self.battleNumberNode = self.uiMap["battle_ui.battle_number_node"] self.battleNumber = self.uiMap["battle_ui.battle_number_node.battle_number"] end function BattleUI:getNumberNode() return self.battleNumberNode end function BattleUI:getBattleNumber() return self.battleNumber end function BattleUI:initHpNode() self.hpProgressLeft = self.uiMap["battle_ui.top_node.bg_l.atk_slider_green"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) self.hpProgressRight = self.uiMap["battle_ui.top_node.bg_r.def_slider_red"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) self.hpProgressLeft.value = 1 self.hpProgressRight.value = 1 self.hpProgressYellowLeft = self.uiMap["battle_ui.top_node.bg_l.atk_slider_yellow"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) self.hpProgressYellowRight = self.uiMap["battle_ui.top_node.bg_r.def_slider_yellow"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) self.hpProgressYellowLeft.value = 1 self.hpProgressYellowRight.value = 1 self.hpTextLeft = self.uiMap["battle_ui.top_node.atk_hp"] self.hpTextRight = self.uiMap["battle_ui.top_node.def_hp"] self.hpPercentLeft = 1 self.hpPercentRight = 1 end function BattleUI:setIsPauseHpProgress(value) if self.isPauseHpProgress == value then return end self.isPauseHpProgress = value if not value then local timeLeft = math.abs(self.hpProgressYellowLeft.value - self.hpPercentLeft) if timeLeft > 0.01 then local delayTime = math.abs(self.hpProgressLeft.value - self.hpPercentLeft)*2 if delayTime > 0.05 then if self.hpProgressYellowLeftSid then self:unscheduleGlobal(self.hpProgressYellowLeftSid) end self.hpProgressYellowLeftSid = self:performWithDelayGlobal(function() self:playHpProgressYellowRightTween(timeLeft) end, delayTime) else self:playHpProgressYellowRightTween(timeLeft) end else if self.hpProgressYellowLeftTween then self.hpProgressYellowLeftTween:Pause() end self.hpProgressYellowLeft.value = self.hpPercentLeft end local timeRight = math.abs(self.hpProgressYellowRight.value - self.hpPercentRight) if timeRight > 0.01 then local delayTime = math.abs(self.hpProgressRight.value - self.hpPercentRight)*2 if delayTime > 0.05 then if self.hpProgressYellowRightSid then self:unscheduleGlobal(self.hpProgressYellowRightSid) end self.hpProgressYellowRightSid = self:performWithDelayGlobal(function() self:playHpProgressYellowRightTween(delayTime) end, delayTime) else self:playHpProgressYellowRightTween(delayTime) end else if self.hpProgressYellowRightTween then self.hpProgressYellowRightTween:Pause() end self.hpProgressYellowRight.value = self.hpPercentRight end end end function BattleUI:playHpProgressYellowLeftTween(time) if self.hpProgressYellowLeftTween == nil then self.hpProgressYellowLeftTween = GFunc.DOBFSliderValue(self.hpProgressYellowLeft, self.hpPercentLeft, time, false) self.hpProgressYellowLeftTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) self.hpProgressYellowLeftTween:SetAutoKill(false) else self.hpProgressYellowLeftTween:ChangeEndValue(self.hpPercentLeft, time, true) self.hpProgressYellowLeftTween:Restart() end end function BattleUI:playHpProgressYellowRightTween(time) if self.hpProgressYellowRightTween == nil then self.hpProgressYellowRightTween = GFunc.DOBFSliderValue(self.hpProgressYellowRight, self.hpPercentRight, time, false) self.hpProgressYellowRightTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) self.hpProgressYellowRightTween:SetAutoKill(false) else self.hpProgressYellowRightTween:ChangeEndValue(self.hpPercentRight, time, true) self.hpProgressYellowRightTween:Restart() end end function BattleUI:refreshAtkHp(num, percent) self.hpTextLeft:setText(GFunc.num2Str(num)) if not self.isPauseHpProgress then if self.hpProgressLeftTween then self.hpProgressLeftTween:Pause() end if self.hpProgressYellowLeftTween then self.hpProgressYellowLeftTween:Pause() end if self.hpProgressYellowLeftSid then self:unscheduleGlobal(self.hpProgressYellowLeftSid) self.hpProgressYellowLeftSid = nil end self.hpProgressLeft.value = percent self.hpProgressYellowLeft.value = percent return end if self.hpPercentLeft == percent then return end self.hpPercentLeft = percent local time = math.abs(self.hpProgressLeft.value - percent)*2 if self.hpProgressLeftTween == nil then self.hpProgressLeftTween = GFunc.DOBFSliderValue(self.hpProgressLeft, percent, time, false) self.hpProgressLeftTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) self.hpProgressLeftTween:SetAutoKill(false) else self.hpProgressLeftTween:ChangeEndValue(percent, time, true) self.hpProgressLeftTween:Restart() end end function BattleUI:refreshDefHp(num, percent) self.hpTextRight:setText(GFunc.num2Str(num)) if not self.isPauseHpProgress then if self.hpProgressRightTween then self.hpProgressrightTween:Pause() end if self.hpProgressYellowRightTween then self.hpProgressYellowRightTween:Pause() end if self.hpProgressYellowRightSid then self:unscheduleGlobal(self.hpProgressYellowRightSid) self.hpProgressYellowRightSid = nil end self.hpProgressRight.value = percent self.hpProgressYellowRight.value = percent return end if self.hpPercentRight == percent then return end self.hpPercentRight = percent local time = math.abs(self.hpProgressRight.value - percent)*2 if self.hpProgressRightTween == nil then self.hpProgressRightTween = GFunc.DOBFSliderValue(self.hpProgressRight, percent, time, false) self.hpProgressRightTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) self.hpProgressRightTween:SetAutoKill(false) else self.hpProgressRightTween:ChangeEndValue(percent, time, true) self.hpProgressRightTween:Restart() end end function BattleUI:refreshSkill(elementMap) if not self.skillNodeCells then return end for elementType, skillEntity in pairs(DataManager.BattleData:getSkillEntities()) do if not self.skillNodeCells[elementType] then return end self.skillNodeCells[elementType]:refresh(skillEntity, elementMap) end end function BattleUI:initGridCell() if self.root.gridCells then self.gridCells = self.root.gridCells self.gridInitOver = true end if self.gridCells and self.gridInitOver then self:onInitGridCellOver() return end local uiMap = self.root:genAllChildren() local parent = uiMap["battle_ui.bg_2.board_node"] self.gridCells = {} self.cellLoadRemianCount = GConst.BattleConst.ROW_COUNT * GConst.BattleConst.COLUMN_COUNT for r = 1, GConst.BattleConst.ROW_COUNT do for c = 1, GConst.BattleConst.COLUMN_COUNT do CellManager:loadCellAsync(GRID_CELL_PATH, GRID_CELL, parent, function(cell) local posId = ModuleManager.BattleManager:getPosId(r, c) self.gridCells[posId] = cell local gameObject = cell:getGameObject() gameObject.name = "grid_cell_" .. posId cell:getBaseObject():setAnchoredPositionX(DEFAULT_X) -- 初始化时放到屏幕外 self.cellLoadRemianCount = self.cellLoadRemianCount - 1 if self.cellLoadRemianCount <= 0 then self.gridInitOver = true self:onInitGridCellOver() self.root.gridCells = self.gridCells end end) end end end function BattleUI:onInitGridCellOver() for posId, cell in pairs(self.gridCells) do local entity = DataManager.BattleData:getGridEntity(posId) if entity then cell:refresh(entity) cell:addTouchListener(function(eventType) if self.battleController then self.battleController:onTouchEvent(eventType, entity:getPosId()) end end) cell:unBindAll() cell:bind(entity, "isDirty", function() cell:refresh(entity, self.curElementType) end) local pos = entity:getPos() cell:getBaseObject():setAnchoredPosition(pos.x, pos.y) entity:setCell(cell) end end end function BattleUI:setController(controller) self.battleController = controller end function BattleUI:showBoardMask(elementType) if not self.gridCells then return end if self.curElementType == elementType then return end self.curElementType = elementType self:refreshBoard() end function BattleUI:refreshBoard() local entities = DataManager.BattleData:getGridEnties() for posId, entity in pairs(entities) do if entity and entity:getCell() then entity:getCell():refresh(entity, self.curElementType) end end end function BattleUI:eliminationAni(sequence, callback) self:showMask(true) if not sequence then if callback then callback() end return end self.boardMask:getTransform():SetAsLastSibling() if self.eliminationAniSeq then self.eliminationAniSeq:Kill() self.eliminationAniSeq = nil end self.eliminationAniSeq = self.root:createBindTweenSequence() self.eliminationAniSeq:AppendCallback(function() if self.boardMask2D then self.boardMask2D.enabled = false end end) if not self.posIdMap then self.posIdMap = {} end for index, info in ipairs(sequence) do if not self.posIdMap[info.posId] then self.posIdMap[info.posId] = true local entity = DataManager.BattleData:getGridEntity(info.posId) if entity and entity:getCell() then local baseObject = entity:getCell():getBaseObject() baseObject:getTransform():SetAsLastSibling() if entity:getSkillId() or info.noAni then baseObject:setAnchoredPositionX(DEFAULT_X) else self.eliminationAniSeq:Insert(index * 0.01, baseObject:getTransform():DOScale(1.3, 0.1)) self.eliminationAniSeq:Insert(index * 0.01 + 0.2, baseObject:getTransform():DOAnchorPos(self:getElementSkillPos(entity:getElementType()), 0.3)) self.eliminationAniSeq:Insert(index * 0.01 + 0.2, baseObject:getTransform():DOScale(1, 0.3)) end end end end self.eliminationAniSeq:AppendCallback(function() self.posIdMap = {} if self.boardMask2D then self.boardMask2D.enabled = true end if callback then callback() end self:refreshSkill() end) end function BattleUI:generateSkillAni(map, callback) if table.nums(map) <= 0 then if callback then callback() end return end self:hideGenerateSkillGridCells() if self.generateSkillAniSeq then self.generateSkillAniSeq:Kill() self.generateSkillAniSeq = nil end self.generateSkillAniSeq = self.root:createBindTweenSequence() for elementType, info in pairs(map) do local entity = self.generateSkillGridEntities[elementType] if entity and entity:getCell() then entity:setSkilId(info.skillId) local cell = entity:getCell() cell:refresh(entity) self.generateSkillAniSeq:AppendCallback(function() local pos = self:getElementSkillPos(elementType) cell:getBaseObject():setAnchoredPosition(pos.x, pos.y) end) local pos = ModuleManager.BattleManager:getPosInfo(info.posId) self.generateSkillAniSeq:Append(cell:getBaseObject():getTransform():DOAnchorPos(pos, 0.5)) end end self.generateSkillAniSeq:AppendCallback(function() if callback then callback() end self:hideGenerateSkillGridCells() end) end function BattleUI:hideGenerateSkillGridCells() if not self.generateSkillGridEntities then local uiMap = self.root:genAllChildren() self.generateSkillGridEntities = {} for name, elementType in pairs(GConst.BattleConst.ELEMENT_TYPE) do local cell = CellManager:addCellComp(uiMap["battle_ui.bg_2.board_node.ani_node.grid_cell_" .. elementType], GRID_CELL) local entity = DataManager.BattleData:getNewGridEntity() entity:setCell(cell) self.generateSkillGridEntities[elementType] = entity end end for _, entity in pairs(self.generateSkillGridEntities) do if entity:getCell() then entity:getCell():getBaseObject():setAnchoredPositionX(DEFAULT_X) end end end function BattleUI:fallGrid(listInfo, callback) self:showMask(false) self.fallAniCount = 0 for posId, info in pairs(listInfo) do self.fallAniCount = self.fallAniCount + 1 local entity = DataManager.BattleData:getGridEntity(posId) local cell = entity:getCell() local posId = entity:getPosId() if cell then local gameObject = cell:getGameObject() gameObject.name = "grid_cell_" .. posId if cell.fallSeq then cell.fallSeq:Kill() cell.fallSeq = nil end local baseObject = cell:getBaseObject() cell.fallSeq = baseObject:createBindTweenSequence() baseObject:setAnchoredPosition(info[1].x, info[1].y) local count = #info cell.fallSeq:Append(baseObject:getTransform():DOLocalPath(info, GConst.BattleConst.ONE_STEP_TIME * count)) cell.fallSeq:AppendCallback(function() self.fallAniCount = self.fallAniCount - 1 if self.fallAniCount == 0 then if callback then callback() end end end) end end end function BattleUI:cacheSkillAni(skillInfo, isPop, callback) local skillInfoCount = #skillInfo if skillInfoCount <= 0 then if callback then callback() end return end self:disableUITouch() if not self.root.skillAniGridEntities then self.root.skillAniGridEntities = {} end for _, entity in ipairs(self.root.skillAniGridEntities) do local cell = entity:getCell() if cell then cell:getBaseObject():setAnchoredPositionX(DEFAULT_X) -- 放到屏幕外 end end local gridEntityCount = #self.root.skillAniGridEntities if gridEntityCount < skillInfoCount then for i = gridEntityCount, skillInfoCount do CellManager:loadCellAsync(GRID_CELL_PATH, GRID_CELL, self.boardCacheNode, function(cell) cell:getBaseObject():setAnchoredPositionX(DEFAULT_X) -- 初始化时放到屏幕外 local entity = DataManager.BattleData:getNewGridEntity() entity:setCell(cell) table.insert(self.root.skillAniGridEntities, entity) if i == skillInfoCount then if isPop then self:doCachePopAni(skillInfo, callback) else self:doCacheAni(skillInfo, callback) end end end) end else if isPop then self:doCachePopAni(skillInfo, callback) else self:doCacheAni(skillInfo, callback) end end end function BattleUI:doCacheAni(skillInfo, callback) if self.cacheSkillAniSeq then self.cacheSkillAniSeq:Kill() self.cacheSkillAniSeq = nil end if not self.root.skillAniGridEntities then if callback then callback() end return end self.boardCacheNode:setVisible(true) self.cacheSkillAniSeq = self.root:createBindTweenSequence() for index, info in ipairs(skillInfo) do local entity = self.root.skillAniGridEntities[index] if entity then entity:setSkilId(info.skillId) local pos = ModuleManager.BattleManager:getPosInfo(info.posId) local cell = entity:getCell() if cell then cell:refresh(entity) local obj = cell:getBaseObject() self.cacheSkillAniSeq:InsertCallback(0.5 * (index - 1), function() obj:setAnchoredPosition(pos.x, pos.y) local gridEntity = DataManager.BattleData:getGridEntity(info.posId) if gridEntity and gridEntity:getCell() then gridEntity:getCell():getBaseObject():setAnchoredPositionX(DEFAULT_X) -- 放到屏幕外 end end) self.cacheSkillAniSeq:Insert(0.5 * (index - 1) + 0.02, obj:getTransform():DOAnchorPos(BF.Vector2(0, 656), 0.5)) end end end self.cacheSkillAniSeq:AppendCallback(function() self.boardCacheNode:setVisible(false) self:enableUITouch() if callback then callback() end end) end function BattleUI:doCachePopAni(skillInfo, callback) if self.cacheSkillAniSeq then self.cacheSkillAniSeq:Kill() self.cacheSkillAniSeq = nil end if not self.root.skillAniGridEntities then if callback then callback() end return end self.boardCacheNode:setVisible(true) self.cacheSkillAniSeq = self.root:createBindTweenSequence() for index, info in ipairs(skillInfo) do local entity = self.root.skillAniGridEntities[index] if entity then entity:setSkilId(info.skillId) local pos = ModuleManager.BattleManager:getPosInfo(info.posId) local cell = entity:getCell() if cell then cell:refresh(entity) local obj = cell:getBaseObject() self.cacheSkillAniSeq:InsertCallback(0.5 * (index - 1), function() obj:setAnchoredPosition(0, 656) end) self.cacheSkillAniSeq:Insert(0.5 * (index - 1) + 0.02, obj:getTransform():DOAnchorPos(pos, 0.5)) self.cacheSkillAniSeq:InsertCallback(0.5 * (index - 1) + 0.52, function() if self.battleController then self.battleController:setGridSkillId(info.posId, info.skillId) end end) end end end self.cacheSkillAniSeq:AppendCallback(function() self.boardCacheNode:setVisible(false) self:enableUITouch() if callback then callback() end end) end function BattleUI:showMask(show) if not self.boardMask then return end self.boardMask:setVisible(show) end function BattleUI:getElementSkillPos(elementType) if not self.skillPoss then self.skillPoss = {} end if not self.skillPoss[elementType] then local cell = self.skillNodeCells[elementType] if not cell then self.skillPoss[elementType] = BF.Vector2(0, 0) else local targetPos = cell:getBaseObject():getTransform().position local sPoint = UIManager:getUICameraComponent():WorldToScreenPoint(targetPos) targetPos = CS.BF.Utils.RectTransformScreenPointToLocalPointInRectangle(self.boardNode:getTransform(), sPoint.x, sPoint.y, UIManager:getUICameraComponent()) self.skillPoss[elementType] = targetPos end end return self.skillPoss[elementType] end function BattleUI:refreshLv() local uiMap = self.root:genAllChildren() if not self.lvSlider then self.lvSlider = uiMap["battle_ui.bg_2.lv_node.slider"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) self.lvDesc = uiMap["battle_ui.bg_2.lv_node.icon.lv_desc"] end local curExp = DataManager.BattleData:getBattleExp() local curNeedExp = DataManager.BattleData:getBattleNeedExp() self.lvSlider.value = curExp / curNeedExp self.lvDesc:setText(DataManager.BattleData:getBattleLv()) end function BattleUI:refreshWave(wave) local uiMap = self.root:genAllChildren() local icon = uiMap["battle_ui.top_node.wave_icon"] local desc = uiMap["battle_ui.top_node.wave_desc"] desc:setText(wave) GFunc.centerImgAndTx(icon, desc, 10) end function BattleUI:clear() if self.alreadyClear then return end self.alreadyClear = true if self.battleNode then self.battleNode:removeAllChildren() end if self.hpProgressYellowLeftSid then self:unscheduleGlobal(self.hpProgressYellowLeftSid) self.hpProgressYellowLeftSid = nil end if self.hpProgressYellowRightSid then self:unscheduleGlobal(self.hpProgressYellowRightSid) self.hpProgressYellowRightSid = nil end if self.hpProgressLeftTween then self.hpProgressLeftTween:Kill() self.hpProgressLeftTween = nil end if self.hpProgressYellowLeftTween then self.hpProgressYellowLeftTween:Kill() self.hpProgressYellowLeftTween = nil end if self.hpProgressRightTween then self.hpProgressRightTween:Kill() self.hpProgressRightTween = nil end if self.hpProgressYellowRightTween then self.hpProgressYellowRightTween:Kill() self.hpProgressYellowRightTween = nil end if self.battleNumberNode then self.battleNumberNode:removeAllChildren() end end return BattleUI