Although this was briefly covered in , I feel that CCMutableArray warrants its own article, much like CCMutableDictionary which will be addressed a bit later.

Declaring a CCMutableArray

NSArrays and NSMutableArrays were a breeze to use, you could store almost anything in them without much regard for the type of the object as long as it was derived from NSObject, so you could easily end up with an array that stored objects of multiple type.

That’s not quite the way CCMutableArrays work. The way I see it, they actually store the data in a std::vector and when you declare a new vector you decide on the type of objects it contains. This means that when you declare a new array you are going to have to do the following:

CCMutableArray<CCSprite *> *sprites = new CCMutableArray<CCSprite *>;


You can also use one of the factory methods for array:

CCMutableArray<CCSprite *> *sprites = 
    CCMutableArray::arrayWithObjects(firstSprite, secondSprite, NULL);
CCMutableArray<CCSprite *> *sprites = 
    CCMutableArray::arrayWithArray(anotherArray);

Interacting with a CCMutableArray

The Cocos2D-x implementation of arrays borrows quite a few methods from the NSArray implementation.

MethodDescription
addObject(T pObject)Adds an object to the array.
addObjectsFromArray(CCMutableArray *pArray)Take all objects from pArray and add them to the current array. The objects will, of course, be retained.
containsObject(T pObject)If the specified object is stored in the array, this method will return true.
count()The number of items stored in the array
getIndexOfObject(T pObject)Returns the index of the object. 1
getObjectAtIndex(unsigned int uIndex)Returns the object stored at specified index
removeObjectAtIndex(unsigned int uIndex, bool bDeleteObject = true)Removes an object from the array. If bDeleteObject is true, the object will also receive a release() call2
removeObjectsInArray(CCMutableArray* pDeleteArray)Remove all objects that are common between the current array and pDeleteArray

1 Big inconsistency. If the object is not found in the array (or the array is empty, or the object is NULL) this method will return 0, just as if the object was stored at the first position in the array. This means that this method is unreliable.

2 This behavior is inconsistent IMO with the NSArray implementation. When you store an object into a CCMutableArray, the object is automatically retained. When you remove the object from the array you have the option of specifying if you would like it to be released. This option doesn’t make a lot of sense, since the object should always be automatically released when removed from an array, and it should be automatically retained when it is added.

Iterating over the array

To iterate over a CCMutableArray you are going to need to use an iterator. First, you need to declare it using the static factory method CCMutableArrayIterator from CCMutableArray.

Using this iterator you will (heh) iterate over the array starting from the beginning to the end with the user of the begin and end methods.

CCMutableArray<CCSprite *>::CCMutableArrayIterator it;
for (it = sprites->begin(); it != sprites->end(); it++) {
    CCSprite *sprite = *it;
    // process the sprite
}

Where to go from here

I will publish a new article soon about using CCArray (which seems to be more well polished than CCMutableArray) and CCMutableDictionary. Check back soon and let me know what you think of this article using the comment form below.

Share this article

Tagged on:         

4 thoughts on “Using CCMutableArray in Cocos2D-x

  • January 11, 2012 at 7:39 pm
    Permalink

    Thanks ! Helped me ! :)))))

    Reply
  • January 11, 2012 at 7:39 pm
    Permalink

    I would be interested by the article about CCArray you mention ! Thanks

    Reply
  • January 21, 2012 at 5:07 pm
    Permalink

    Hi there,

    Nice blog explaining CCMutableArray.

    Is there a way in cocos2dx to convert a CCMutableArray to just a CCArray.

    for example if you want to iterate over child objects in a CCNode

    you would have to do this……

    CCArray *children = this->getChildren();
    CCSprite *currentSprite;

    for (int i=0;icount();i++){

    currentSprite = (CCSprite*) children->objectAtIndex(i);
    //do something with currentSprite….

    }

    i’ve tried to use the following but it crashes for some reason??

    CCObject* obj;
    CCSprite *currentSprite;
    CCARRAY_FOREACH(arr,obj)
    {
    currentSprite = (CCSprite*) obj
    //do something. static cast up to do more
    }

    Cool looking site by the way!!!

    Andy

    Reply
  • May 6, 2012 at 9:10 pm
    Permalink

    What about release the array if you alloc it with new?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Email
Print