ZOrder

一、声明

笔者以cocos2d框架的cocos2d-x-3.3rc0版本源码做分析。本文属于笔者原创,允许转载和分享,但请注明文章出处。

二、简介

ZOrder

ZOrder顾名思义就是节点(Node对象)在Z轴上的排序,这样一来ZOrder越小就越优先显示。每个节点(Node对象)可以持有多个子节点,组成节点树(关于节点树的介绍查看《Cocos2d之Node类详解之节点树》一文)。ZOder表示了节点树中每个子节点显示的优先级。值得注意的是,节点树中子节点的ZOder可能会一样,这种情况下父节点就根据每个子节点的 _orderOfArrival 属性来判断子节点的显示顺序。orderOfArrival是表示子节点被添加的顺序,越小则子节点显示的优先级越高。

Node类中声明了两个ZOrder属性。

int _localZOrder;               ///< Local order (relative to its siblings) used to sort the node
float _globalZOrder;            ///< Global order used to sort the node

LocalZOrder

前面提到过,每一个父节点都可以持有一个节点树。节点树中的子节点的 _localZOrder 属性会作为该子节点与其他兄弟姐妹子节点间排序的关键字。节点树的父节点会依据这个值来对所有的子节点进行排序。_localZOrder < 0 表示子节点放在节点树的左子树中,_localZOrder >= 0 表示子节点放在节点树的右子树中。

三、源码详解

设置LocalZOrder

相关函数声明。

复制代码
/**
     LocalZOrder is the 'key' used to sort the node relative to its siblings.

     The Node's parent will sort all its children based ont the LocalZOrder value.
     If two nodes have the same LocalZOrder, then the node that was added first to the children's array will be in front of the other node in the array.
     
     Also, the Scene Graph is traversed using the "In-Order" tree traversal algorithm ( http://en.wikipedia.org/wiki/Tree_traversal#In-order )
     And Nodes that have LocalZOder values < 0 are the "left" subtree
     While Nodes with LocalZOder >=0 are the "right" subtree.
     
     @see `setGlobalZOrder`
     @see `setVertexZ`
     */
    virtual void setLocalZOrder(int localZOrder);

    CC_DEPRECATED_ATTRIBUTE virtual void setZOrder(int localZOrder) { setLocalZOrder(localZOrder); }
    
    /* Helper function used by `setLocalZOrder`. Don't use it unless you know what you are doing.
     */
    CC_DEPRECATED_ATTRIBUTE virtual void _setLocalZOrder(int z);

    /**
     * Gets the local Z order of this node.
     *
     * @see `setLocalZOrder(int)`
     *
     * @return The local (relative to its siblings) Z order.
     */
    virtual int getLocalZOrder() const { return _localZOrder; }
    CC_DEPRECATED_ATTRIBUTE virtual int getZOrder() const { return getLocalZOrder(); }
复制代码

从声明中可以看出,设置LocalZOrder属性的主要函数是 setLocalZOrder(int localZOrder),下面看这个函数的实现。

复制代码
void Node::setLocalZOrder(int z)
{
    if (_localZOrder == z)
        return;
    
    _localZOrder = z;
    if (_parent)
    {
        _parent->reorderChild(this, z);
    }

    _eventDispatcher->setDirtyForNode(this);
}
复制代码

    从源码可以看出,如果Node对象存在父节点(也就是说该对象在父节点的节点树中),Node对象改变 _localZOrder 的值后会调用父节点的 reorderChild 函数对子节点进行重新排序(笔者在《Cocos2d之Node类详解之节点树(二)》一文的“节点树重排序”部分有介绍 reorderChild 函数)。

### Android 中 ZOrder 的概念 在 Android 系统中,ZOrder 是指图层的堆叠顺序。它决定了多个视图(View)、Surface 或窗口之间的绘制优先级[^1]。具体来说,具有较高 Z 值的对象会覆盖较低 Z 值的对象。 #### Surface 和 View 的关系 - **Surface** 是一种特殊的缓冲区对象,用于渲染图形数据到屏幕上。它可以独立于主线程运行,并支持硬件加速。 - **View** 则是 Android UI 层的核心组件之一,通常由应用开发者直接操作。所有的 `View` 都会被封装在一个 `Surface` 上进行渲染。 当涉及到复杂的界面布局时,可能会同时存在多种类型的绘图表面,比如普通的 `View`、`SurfaceView` 以及更高层次的窗口管理器控制下的其他 Surfaces。 #### 图层合成过程 Android 的 Window Manager Service 负责协调不同应用程序间的窗口排列及其对应的 ZOrder 设置。对于单个 Activity 内部而言: 1. 所有的子控件 (Child Views) 将被放置在其父容器 (`ViewGroup`) 定义的空间范围内; 2. 如果某个特定区域既属于常规 View 又关联了一个单独的 Surface,则需要通过设置参数来调整它们之间相对位置; 3. 合成阶段按照指定好的 Z-order 对所有参与元素逐一处理并输出至屏幕。 例如,在使用 `SurfaceView` 进行视频播放或其他高性能需求场景下,默认情况下该组件位于最底层,因为它的设计初衷就是提供一个专用的 drawing surface 来减少复杂度和提升效率。如果希望改变这种默认行为,可以尝试调用相应 API 方法重新定义其层级关系。 ```java // 修改 SurfaceView 的 ZOrder surfaceView.setZOrderOnTop(true); // 让 SurfaceView 处于顶层 ``` 上述代码片段展示了如何让 `SurfaceView` 显示在其它标准 views 的上方。 ### 解决图层显示问题的方法 遇到图层叠加异常或者预期效果不一致的情况时,可以从以下几个方面入手排查: - 检查是否有冲突性的透明度属性影响实际呈现结果; - 确认各个部件是否正确定位及尺寸设定无误; - 使用调试工具查看实时渲染状态以便发现问题所在。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值