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__++)
用法如下:
例子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就行
关于数组的一些用法遍历操作就介绍到这