原文地址:https://segmentfault.com/a/1190000038642307
前言
在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、三步,直至栈为空。
- 将下一个子节点入栈,重复上述操做,直至遍历完根节点的所有子节点。