cocos2d-x 3.0 beta: the new Vector class

cocos2d-x 3.0 beta was recently released. one of the big new additions is the introduction of new container classes.

up until now, the cocos2d-x’s container classes were modelled after objective-c’s container classes (NSArray, NSDictionary, etc). now they are modelled after the standard c++ library’s containers (std::vector<T>, std::map<T>).

this post will show you a simple example of converting code from using the old CCArray class to the new Vector class.

consider this cocos2d-x v2.x code:

// HelloWorld.h
class HelloWorld : public cocos2d::CCLayer
{
    //  ...
    cocos2d::CCArray *_bullets;
};


// HelloWorld.cpp
using namespace cocos2d;

bool HelloWorld::init()
{
    if (!this->CCLayer::init())
        return false;

    //  ...

    //  bullets
    this->_bullets = CCArray::createWithCapacity(100);
    this->_bullets->retain();
}

let’s review some things about the old CCArray class:

the new, 3.0 way might look like this:

// HelloWorld.h
class HelloWorld : public cocos2d::CCLayer
{
    //  other stuff...

    cocos2d::Vector<cocos2d::Sprite *> _bullets;
};

// HelloWorld.cpp
using namespace cocos2d;

HelloWorld::HelloWorld() : _bullets(100)
{
}

things to note here:

somewhere in some shooting code you might have something like this:

cocos2d-x v2.x:

//   add a bullet
CCSprite *bullet = CCSprite::create("circle.png");
this->_bullets->addObject(bullet);  //  retains bullet

cocos2d-x v3.0 beta:

//   add a bullet
Sprite *bullet = Sprite::create("circle.png")
this->_bullets.pushBack(bullet);  //  retains bullet

not much different here except for the name change (pushBack is named similarly to the STL’s push_back method), and the fact that you use “.” instead of “->” (because _bullets is no longer a pointer).

removing an item:

v2.x:

this->_bullets->removeObject(bullet);

v3.0beta:

this->_bullets.eraseObject(bullet);

looping through the array:

v2.x:

//  loop through bullets
CCObject *obj;
CCARRAY_FOREACH(this->_bullets, obj)
{
    CCSprite *bullet = (CCSprite *)obj;
    //  do something with bullet.
    if (bullet->getPositionX() > 160)
    {
        //  ...
    }

}

v3.0beta:

//  loop through bullets
for (auto bullet: this->_bullets)
{
    //  do something with bullet.
    //  no need to cast in this case
    if (bullet->getPositionX() > 160)
    {
        //  ...
    }
}

and finally, in your destructor, you’d want to clean up the array so as not to leak memory:

v2.x:

HelloWorld::~HelloWorld()
{
    //  release stuff
    this->_bullets->release();
}

v3.0beta:

HelloWorld::~HelloWorld()
{
    //  nothing to do! _bullets manages its storage automatically when it falls out of scope
}

comments

comments powered by Disqus