cocos2dx的zorder值可以相同,zorder值越大越后渲染,相同时,优先渲染先添加到显示列表的对象。
这是目前的渲染机制,但是如果几个对象的zorder值相同,我又想在将一个新的对象,放到他们中间某个层级上,就无从下手了。
尝试了很多种方法都没能解决我的问题,所以最后决定参照AS3.0的index值排序逻辑,重写Node的相关方法。
如果你们有其他解决办法,麻烦指导一下。如果也有相同困扰且没有解决,可以参照我的代码来用。
代码如下:
--################################################
--
1. 以下重写了Node的几个基本方法,目的是为了解决cocos2dx中,zorder值可以设置为相同值,
导致无法向两个order值相同的对象中间添加一个新的显示对象的问题。
2. 逻辑是参照AS3.0的对象列表和index值排序方式,有区别的是,这里的index值也就是zorder值
是从1开始而不是0。
]]--
local Node_getChildren = Node.getChildren
local Node_getLocalZOrder = Node.getLocalZOrder
local Node_setLocalZOrder = Node.setLocalZOrder
local Node_addChild = Node.addChild
local Node_removeFromParent = Node.removeFromParent
local Node_removeChildByTag = Node.removeChildByTag
function Node:getChildren()
if self._override_getChildren_children then
return self._override_getChildren_children
end
local childList = Node_getChildren(self)
self._override_getChildren_children = {}
for i,v in ipairs(childList) do
self._override_getChildren_children* = Node_setLocalZOrder(v, i)
end
return self._override_getChildren_children
end
function Node:getLocalZOrder()
local parent = self:getParent()
if parent then parent:getChildren() end
return Node_getLocalZOrder(self)
end
function Node:setLocalZOrder(zorder)
local parent = self:getParent()
if parent then parent:getChildren() end
return Node_setLocalZOrder(self, zorder)
end
function Node:addChild(child, zorder, tag)
if child and child:getParent() then
child:removeFromParent()
end
local childList = self:getChildren()
local total = #childList
if zorder == nil then
zorder = total + 1
else
if zorder < 1 then zorder = 1 end
if zorder > total + 1 then zorder = total + 1 end
end
for i=total + 1,zorder + 1,-1 do
childList* = childList*
childList*:setLocalZOrder(i)
end
childList = child
if tag then
Node_addChild(self, child, zorder, tag)
else
Node_addChild(self, child, zorder)
end
return self
end
function Node:removeFromParent()
local parent = self:getParent()
if not parent then return self end
local list = parent:getChildren()
local zorder = table.indexof(list, self)
for i=zorder,#list - 1 do
list* = list*
list*:setLocalZOrder(i)
end
list#list] = nil
return Node_removeFromParent(self)
end
function Node:removeChildByTag(tag)
local list = self:getChildren()
local zorder
for i,v in ipairs(list) do
if v:getTag() == tag then
zorder = i
break
end
end
if zorder ~= nil then
for i=zorder,#list - 1 do
list* = list*
list*:setLocalZOrder(i)
end
list#list] = nil
end
return Node_removeChildByTag(self, tag)
end
--################################################################################
**********
将上面代码放到NodeEx.lua中,位置在 local Node = cc.Node 下面,就可以直接使用了。
不过为了方便维护,建议单独做个文件,游戏开始前载入。