cocos2dx-lua 遞歸開啓多層子節點的透明度設置

前言

在cocos2dx-lua中若是要設置父節點和子節點的透明度,能夠使用父節點的setCascadeOpacityEnabled方法開啓節點透明度設置,否則沒法設置節點透明度。
可是這個方法有個缺陷,當一個節點中有多層子節點時,沒法開啓子節點的子節點的透明度設置。網上常見的解決方案是去改引擎源碼,將節點的透明度設置默認爲開啓。這裏提供另外一種解決方案。node

遞歸開啓子節點的透明度

爲了能開啓所有子節點的透明度設置,採用遞歸的方式去遍歷節點的所有子節點,由於節點的層級實際上不會搞不少層(太多層想取出來進行某些操做會很麻煩),因此一般不用擔憂棧溢出的問題。
先貼上源碼,方便介紹(已寫成工具類方便調用):工具

local SetOpacityUtil = class("SetOpacityUtil")

function SetOpacityUtil:ctor(node)
    self.children = {};
    self.node = node;
end

--
-- @description: 先遞歸遍歷子節點,將子節點插入table中,
-- 若是在遍歷的過程當中遇到沒有子節點的節點或者已經遍歷過的節點,就開啓
-- 透明度設置,已開啓設置的節點從table中移除,當table爲空時結束遞歸。
--
function SetOpacityUtil:_setCascadeOpacity()
    if #self.children == 0 then
        return nil
    end
    -- 爲子節點開啓透明度設置
    if not self.children[#self.children].node:getChildren() or
        self.children[#self.children].isForEach then
        self.children[#self.children].node:setCascadeOpacityEnabled(true)
        table.remove(self.children, #self.children)
    end
    if #self.children == 0 then
        return nil
    end
    -- 若是有子節點,且該節點未遍歷,就遍歷它,並將該節點的子節點加到table中
    if self.children[#self.children].node:getChildren() and
        not self.children[#self.children].isForEach then
        self.children[#self.children].isForEach = true
        for _, child in ipairs(self.children[#self.children].node:getChildren()) do
            table.insert(self.children, {node = child, isForEach = false})
        end
    end
    return self:_setCascadeOpacity()
end

--
-- @Author: Y.M.Y
-- @description: 遞歸開啓UI節點的子節點的設置透明度選項
--
function SetOpacityUtil:setCascadeOpacity()
    for _, v in pairs(self.node:getChildren()) do
        table.insert(self.children, {node = v, isForEach = false})
        self._setCascadeOpacity()
    end
    self.node:setCascadeOpacityEnabled(true)
end

return SetOpacityUtil

代碼的實現思路是:lua

  • 先將根節點的一個子節點壓入棧中;
  • 遇到沒有子節點的節點或已經遍歷過的節點就直接開啓節點的透明度設置,並出棧;
  • 有子節點且沒被標記爲已遍歷過的節點,就遍歷該節點的所有子節點並逐一入棧。
  • 重複2、三步,直至棧爲空。
  • 將下一個子節點入棧,重複上述操做,直至遍歷完根節點的所有子節點。
相關文章
相關標籤/搜索