popupWindowQueue_modle - woodelf-treetop/rcwiki GitHub Wiki

前言

弹窗队列系统。

主要功能:在进入游戏的时候,会在主页强制推送一些界面。目前有“七日签到界面”、“赛季结算界面”、“广告界面”。后面看需求增加或删减。

设计的说明和想法

核心逻辑写在了 HudStage.lua 里。

当时第一时间想的是栈的数据形态,但是需求需要这些界面的开启有优先级,所以在存储完所有的界面后,做了优先级排序。

这里核心的接口有三个:

function HudStage:PushPanel(_panelName, _InitData, _IsAdd)
    if _panelName then
        self:SetPanelData(_panelName, _InitData, _IsAdd)
    end
end

function HudStage:SetPanelData(_panelName, _InitData, _IsAdd)

    if not openPanelData then
        openPanelData = {}
        openState = false

        PanelOpenCount = {}
    end

    if not _IsAdd then
        self:SetScenceAdd(_panelName)
    end

    -- logError("_panelName:"..tostring(_panelName))
    -- logError("_IsAdd:"..tostring(_IsAdd))
    if self:CheckExistOrHasOpen(_panelName) or not _IsAdd then
        -- logError("This panel has been existing Or has already opened ->[HudStage.lua]")
        return
    end

    local data = {}

    if _panelName == CtrlPanelName.SeasonAccountPanel then  --结算界面
        data.CtrlPanelName = CtrlPanelName.SeasonAccountPanel
        data.InitData = _InitData
        data.PriorityLv = 4
    elseif _panelName == CtrlPanelName.DailyBonusPanel then --七日签到界面
        data.CtrlPanelName = CtrlPanelName.DailyBonusPanel
        data.InitData = _InitData
        data.PriorityLv = 1
    elseif _panelName == CtrlPanelName.PushNewsPanel then --广告界面
        data.CtrlPanelName = CtrlPanelName.PushNewsPanel
        data.InitData = _InitData
        data.PriorityLv = 2
    end
    PanelOpenCount[_panelName] = false
    table.insert(openPanelData, data)

    --按照优先级排序
    if #openPanelData > 1 then
        table.sort(openPanelData, function(a,b)
            return a.PriorityLv > b.PriorityLv
        end)
    end

    self:SetScenceAdd(_panelName)
end
function HudStage:PopPanel()
    if GuideManager.isShow then
        -- logError("当前处于引导中")
        return
    end

    if openState then
        -- logError("当前有弹窗界面正在开启...")
        return
    end
    local data = self:GetPanelData()
    if data then
        openState = true
        --这里注释的目的是:当时广告界面的代码框架是旧版的。所以这里做了判断,后来又成新的ui框架了,所以就统一了Open接口
        -- if data.CtrlPanelName == CtrlNames.PushNews then
        --     CtrlManager.GetCtrl(CtrlNames.PushNews).Awake()
        -- else
        --     CtrlPanelManager.OpenPanel(data.CtrlPanelName, data.InitData)
        -- end
        CtrlPanelManager.OpenPanel(data.CtrlPanelName, data.InitData)
        PanelOpenCount[data.CtrlPanelName] = true
        self:RemoveOnePanelData(data.CtrlPanelName)

    else
        -- logError("暂时没有数据了")
    end
end
--将开着的界面的state设置为false
function HudStage.CloseOpenState()
    openState = false
end
  • PushPanel:这里是将初始化好的界面压入这个队列里,这里需要注意的点后面会讲到。
  • PopPanel:这里是将队列里优先级最高的界面取出(显示出来)。
  • CloseOpenState:每一个需要展示的界面,在关闭它的时候需要调用这个函数,用来告知下次PopPanel是可行的。

PushPanel

这个函数用到了三个参数,_panelName_InitData 是界面open的支持参数。下面着重说一下 _IsAdd的作用。

_IsAdd:由于我们预定义的开启界面不一定都会有数据,比如,不一定每天都会有广告,赛季结算的数据只有结算后才有。但是我们这个队列开始运行是在所有的界面都准备完毕了才会运行,这时不用弹出的的我们也会告知这个队列说“这个界面已经准备完毕”,只是不会有去初始化它的openPanelData

这里就以广告为例子。
需要判断所有的条件,去选择 _IsAdd 用true还是false,这些条件都是互斥的。所以如果有新的界面需要加入到这个队列,那么需要PushPanel所有的条件。

PopPanel

PopPanel的启动机制,我们在所有界面全部”准备“完毕后会在SetScenceAdd函数调用PopPanel方法,所有的弹窗队列都是基于主界面的,所以当我们关闭一个弹窗界面时,会调用到主界面的 Hud_MainPanel.ReShow方法里,会再次PopPanel,直到队列里没有数据了。

还有一种情况是,我启动游戏后直接进入战场了,那么从战场回来后是第一次创建主界面,所以不会走到上述说的Hud_MainPanel.ReShow方法里,即我们需要在Hud_MainPanel.InitPanel里做PopPanel,然后直到队列里没有数据。

注意的地方

  • 上述说的多地方调用PopPanel,这里不会引起冲突,我们用openState参数做限制。
  • 在增加或者删减界面的时候,需要 ConstNum 字段做修改,设置一个等待界面个数。另外还需要在 SetPanelData 里做数据处理。
⚠️ **GitHub.com Fallback** ⚠️