CCArray

CCArray也是cocos2d-x自己写的类。它相当于是objc的NSArray。在cocos2d-x中是没有NSArray的概念的(NSArray和NSMutableArray的唯一区别就是一个不可以改变数组中含有的对象,另一个可以改变)。但是CCArray也有一个小问题。首先,CCArray是不能使用new的方式创建的。其次,使用CCArray::array()创建的数组,即使这个数组已经是当前类的成员变量,也必须要做一次retain,否则的话在创建数组的函数返回的时候,CCArray就会被直接释放掉了。由于这个问题也无法通过编译时候暴露出来,而且在objc中创建自动释放的NSArray类型的成员变量的时候是不需要retain的,所以当我从objc转为使用cocos2d-x的时候,经常会忘记做retain,多次导致了程序在其他函数中使用该成员变量的时候出现错误。



一.基本用法

1.声明初始化变量

C++
1
2
3
cocos2d :: CCArray *   pArray ;
pArray = CCArray :: createWithCapacity ( 100 ) ;
pArray -> retain ( ) ; //如果保留成员变量的话,此处必须retain,否则会崩溃,因为标记了autorelease

2.添加元素到数组

C++
1
2
CCSprite *   pRet = CCSprite :: create ( "test.png" ) ;
pArray -> addObject ( pRet ) ; //将pRet添加到数组0位置,此处会调用一次pRet的retain

3.删除元素

C++
1
2
3
//下面这两个函数都能够实现删除元素的效果
pArray -> removeObject ( pRet ) ; //第二参数为是否调用release,默认为true
pArray -> removeObjectAtIndex ( 0 ) ; //删除o位置上的元素

4.遍历

1).使用ccarray中的宏进行遍历

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
CCObject *   pObj ;
//正向
CCARRAY_FOREACH ( s_pBulletArray , pObj )
{
     CMapNode *   pNode = ( CMapNode * ) pObj ;
     //...
}
//逆向
CCARRAY_FOREACH_REVERSE ( s_pBulletArray , pObj )
{
     CMapNode *   pNode = ( CMapNode * ) pObj ;
     //...
}

2).for循环遍历

C++
1
2
3
4
for   ( unsigned   int   i   =   0 ;   i   < s_pBulletArray -> count ( ) ;   ++ i )
{
     CCNode *   pObj = ( CCNode * ) s_pBulletArray -> objectAtIndex ( i ) ;
}

 

二.注意事项

1.创建一个CCArray后如果不是立刻使用的话一定要调用retain,增加引用计数,不然会被自动释放!

2.删除CCArray中的元素时最好默认内部调用一次release,不然可能会内存泄露!

3.遍历时删除元素

C++
1
2
3
4
5
6
7
8
9
10
11
//判断条件删除时,最好能够逆向遍历删除,这样不会漏掉任何元素
for   ( int   i   =   arr -> count ( ) - 1 ;   i >= 0   ;   -- i )
{
     CMonster *   pObj = ( CMonster * ) arr -> objectAtIndex ( i ) ;
     bool          isCollide   =   false ;
     isCollide   = rect . intersectsRect ( pObj -> getCollideRect ( ) ) ;
     if   ( isCollide )
     {
         arr -> removeObject ( pObj ) ;
     }
}

 

 三.什么时候会用到CCArray?

 

1.每一个CCNode的children本质就是一个CCArray,这样我们就可以通过getChildren()获得array,进行操作!

 

2.对于CCSequence如果只有到运行时才能知道有个少个动作时,我们就可以声明一个CCArray然后将动作addObject(),最后通过一个array来创建CCSequence,例如下面这段代码:

C++
1
2
3
4
5
6
7
8
9
10
11
12
//所有的路径节点
CCArray   * array   =   CCArray :: createWithCapacity ( 20 ) ;
float   dt = 1 / ( m_pProperty -> fMoveSpeed ) ;
CCPoint  point ( - 1 , - 1 ) ;
for   ( UINT   i = 0 ; i < CGlobal :: getGameMap ( ) -> m_PathNode . size ( ) - 1 ; ++ i )
{
     array -> addObject ( CCMoveTo :: create ( dt , point ) ) ;
}
//移动完毕的回调
array -> addObject ( CCCallFunc :: create ( this , callfunc_selector ( CMonster :: onArrive ) ) ) ;
 
CCSequence *   pAct = CCSequence :: create ( array ) ;

 

3.对于一个CCSprite,我们肯定需要把它addChild到parent上,这样他才能显示出来,这样的话parent上就会有好多child,但是我们要遍历只是其中的一部分(例:场景的地图上有好多种花,我们都会把它们添加到同一个parent上,这时候策划说其中的一种花会被怪物踩死?纳尼….,这个时候我们就需要唉将能被踩死的花加入到parent上时同时加入到一个CCArray中去….),这样我们用的时候遍历这个数组就可以了,而不是遍历这个children!

 

4.多谢@子龙山人 大大的添加,CCArray还可以内存预分配,比如预先生成一堆子弹,然后加到CCArray中,再从这个CCArray中去重用子弹。这样可以提高游戏效率。消失的子弹只需要设置为Invisible就可以了。这个在做射击类游戏中会大量使用的!

5.还有其他用法?发评论告诉我!

分享到: 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值