zoukankan      html  css  js  c++  java
  • cocos2d-x 之 CCArray 的遍历(3)

    cocos2d-x中CCArray的遍历,需要几个宏。现代C++程序设计建议尽量不要使用宏,所以数组的遍历也可以自己写。

    但cocos2d-x官方已经提供了几个方便数组遍历的几个宏,用好了,能方便许多 。下面就介绍一下第一个宏

    1   CCARRAY_FOREACH ,此宏的定义如下

    #define CCARRAY_FOREACH(__array__, __object__)                                                                         
        if ((__array__) && (__array__)->data->num > 0)                                                                     
        for(CCObject** __arr__ = (__array__)->data->arr, **__end__ = (__array__)->data->arr + (__array__)->data->num-1;    
        __arr__ <= __end__ && (((__object__) = *__arr__) != NULL/* || true*/);                                             
        __arr__++)

    宏的作用就是把数组__array__ 从头到尾,把里面的每个元素分别赋值给 __object__ ,这样就可以对每个元素进行操作了。

    用法如下:

    例子1 :

    有一个数组 CCArray* arr;//假如已经初始化了,数组里面有元素

    CCObject* obj = NULL;

    CCARRAY_FOREACH(arr,obj)

    {

      //your code

    }

    例子2 :

    CCNode的成员函数onEnter()中,有一段代码是遍历此节点的所有的子节点是否正在运行,代码如下,只需要看中文注释那几行代码即可

    void CCNode::onEnter()
    {
        //fix setTouchEnabled not take effect when called the function in onEnter in JSBinding.
        m_bRunning = true;
    
        if (m_eScriptType != kScriptTypeNone)
        {
            CCScriptEngineManager::sharedManager()->getScriptEngine()->executeNodeEvent(this, kCCNodeOnEnter);
        }
    
        //Judge the running state for prevent called onEnter method more than once,it's possible that this function called by addChild  
        if (m_pChildren && m_pChildren->count() > 0)
        {
    
            //数组遍历,只需要看下面代码
            CCObject* child;
            CCNode* node;
    
            //把数组m_pChilden中的所有子节点分别赋值给child
            CCARRAY_FOREACH(m_pChildren, child)
            {
                node = (CCNode*)child;//将child转换成数组中元素的类型
                if (!node->isRunning())//对数组中元素进行判断是否正在运行
                {
                    node->onEnter();//如果正在运行,调用onEnter函数
                }            
            }//end loop
        }
    
        this->resumeSchedulerAndActions();   
    }

    还有一个宏也是进行数组遍历的。

    2 CCARRAY_FOREACH_REVERSE

    定义如下

    #define CCARRAY_FOREACH_REVERSE(__array__, __object__)                                                                  
        if ((__array__) && (__array__)->data->num > 0)                                                                      
        for(CCObject** __arr__ = (__array__)->data->arr + (__array__)->data->num-1, **__end__ = (__array__)->data->arr;     
        __arr__ >= __end__ && (((__object__) = *__arr__) != NULL/* || true*/);                                              
        __arr__--)

    这个宏与上一个宏CCARRAY_FOREACH 的作用是一样的,也是进行数组的遍历,但是CCARRAY_FOREACH 是从头到尾开始遍历,

    CCARRAY_FOREACH_REVERSE 是从尾部向首部开始遍历的。

    具体用法同上。自己可以举例进行遍历,验证一下。

    3  arrayMakeObjectsPerformSelector

    这个宏是对数组中的每一个元素分别调用 func 函数,pArray是数组,func是要调用的函数,elementType是元素的类型,比如数组中存放的是CCSpirte* ,那么elementType就是CCSpirte

    定义如下:

    #define arrayMakeObjectsPerformSelector(pArray, func, elementType)    
    do {                                                                  
        if(pArray && pArray->count() > 0)                                 
        {                                                                 
            CCObject* child;                                              
            CCARRAY_FOREACH(pArray, child)                                
            {                                                             
                elementType pNode = (elementType) child;                  
                if(pNode)                                                 
                {                                                         
                    pNode->func();                                        
                }                                                         
            }                                                             
        }                                                                 
    }                                                                     
    while(false)

    例子:

    比如有一个数组 arrSP ,数组存放的全是CCSpirte ,我想对arrSP中所有的精灵调用它的draw()函数

    那么我可以这样用

    arrayMakeObjectsPerformSelector(arrSP,draw,CCSpirte*);  //注:别忘了后面的分号 ; 哦,如果不加分号,会报错的。

    其实在宏的定义里面的最后一句 while(false)后面就可以直接加个分号,可以减少出错的概率。

    还有最后一个宏,是调试用的。可以了解一下。


    4 CCARRAY_VERIFY_TYPE
    这个宏是检查数组中的元素的类型是否正确的。主要用到了dynamic_cast 运算符,dynamic_cast 可以在执行期决定真正的类型,宏的定义如下
    #if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
    #define CCARRAY_VERIFY_TYPE(__array__, __type__)                                                                 
        do {                                                                                                         
            if ((__array__) && (__array__)->data->num > 0)                                                           
                for(CCObject** __arr__ = (__array__)->data->arr,                                                     
                    **__end__ = (__array__)->data->arr + (__array__)->data->num-1; __arr__ <= __end__; __arr__++)    
                    CCAssert(dynamic_cast<__type__>(*__arr__), "element type is wrong!");                            
        } while(false)
    #else
    #define CCARRAY_VERIFY_TYPE(__array__, __type__) void(0)
    #endif

    宏定义中有这样一句  CCAssert(dynamic_cast<__type__>(*__arr__), "element type is wrong!");   

    这就是转换的关键所在。

    并且只有定义了 COCOS2D_DEBUG 宏而且还大于 0 的情况下 ,CCARRAY_VERIFY_TYPE才有意义

    比如下面第一种方法定义COCOS2D_DEBUG就没有起作用,第二种是起作用的。

    第一种方法  :#define COCOS2D_DEBUG

    第二种方法  :#define COCOS2D_DEBUG   1 //只要大于0就行

    
    
    关于数组的一些用法遍历操作就介绍到这


    欢迎访问作者的helloworld的个人博客:
    https://www.helloworld.net/jiulu

    同时也可以加作者的微信:daitukeji
    也可以扫下面的二维码添加
    ![image](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/f0b62fd75da7cbeba3b77965f4e26845.png)



  • 相关阅读:
    【Java】String和Date、Timestamp之间的转换
    pl/sql改为汉语窗口的办法
    MySql生成随机数
    ETL概念
    oracle数据库中序列使用讲解
    oracle中的merge into用法解析
    mysql实现自动更新时间戳
    3.6:Linux touch命令:修改文件的时间戳
    3.5:Linux rmdir命令:删除空目录
    3.4:Linux mkdir命令:创建目录(文件夹)
  • 原文地址:https://www.cnblogs.com/start1225/p/3530969.html
Copyright © 2011-2022 走看看