How to use a progress bar in cocos2d-x and C++

by on Jun.14, 2013, under Cocos2d-x, Technical posts

Sometimes in our games we need to add a progress bar. We can use it to show the remaining fuel of a starship, car, … . We can also use it to show the loading progress between two different scenes, loading a new level, … . There are few examples out there on how to do it, but they are mainly for the Iphone version of Cocos2d-x. I would like to share with you how I build mine to show the remaining fuel of our balloon.

I have started building my example following this example for the Iphone version of cocos2d that you can find here. We are going to use the following 2 images, the first one for the border of our “fuel” bar. The second one a gradient to show the amount of remaining “fuel” (I take no credit for the images, as they are the same as in the example mentioned above):

Fuel progress bar border

Fuel progress bar gradient

After this introduction then, let’s get started. First of all we are going to create a CCSprite containing the border image.
CCPointer <CCSprite> fuelBarBorder; 

fuelBarBorder = 
 CCSprite::createWithSpriteFrameName ("bt_progressbarborder.png" ); 

fuelBarBorder->setPosition(ccp(100,100)); 

this->addChild(fuelBarBorder,1);

As you can see in the code above, first we declare an object CCSprite (pointer). This is a smart pointer in cocos2d-x, if you don’t know how to use them (you should!!!!), you can exchange that line by “CCSprite *fuelBarBorder;”. Our first step afterwards, is to initialize our CCSprite with the contents of the border image file. I am using an image contained inside my texture sprite sheet file (please refer to here in case you don’t know how to use them). After initializing our CCSprite object, we just located in our game screen and last we add it to our scene.

Nothing complicated or new till here, right? :-). It is time to start building our CCProgressTimer object (the progress bar object). We will do it as follows:

  
// CCProgresstimer object (smart pointer) 
CCPointer <CCProgressTimer> fuelBar; 
fuelBar = CCProgressTimer::create(
     CCSprite::createWithSpriteFrameName ("bt_progressbar.png" ));
// Set this progress bar object as kCCProgressTimerTypeBar (%)
fuelBar->setType(CCProgressTimerType::kCCProgressTimerTypeBar);

// Set anchor point in 0,0 and add it as a child to our border sprite
fuelBar->setAnchorPoint(ccp(0,0));

fuelBar->setBarChangeRate(ccp(1,0)); // To make width 100% always
fuelBar->setTag(1);                  // Tag our object for easy access

fuelBarBorder->addChild(fuelBar,50); // Add it inside the border sprite

As you can see in the code above, first of all we define an CCProgressTimer object. After that, in order to initialize it we pass an CCSprite object containing the image to fill our progress bar. Once we have initialized our object, we will perform some “customization” in order to build it as we need:

  • Type: We define it as “kCCProgressTimerTypeBar” because we will use our progress bar as a percentage (we will see how later).
  • AnchorPoint: at 0,0 because we will add it as a child to our “fuelBarBorder” object defined above. Then using the co-ordinates origin, will add it just “inside” our border.
  • BarChangeRate: This value is important, as will define the expansion coordinates of our bar. In other words, if we would like to expand / contract only width, width & height or only height. This will be used for different types of bars, as vertical /horizontal  bars for example.
  • Tag: Number for easy access later on ( as any other object in our scene).

So, we have already inserted our progress bar into our scene. How we use it now? In our update method (or wherever we need to update the value for our fuel progress bar) we will use the following method to assign the value we would like to be displayed by our progress bar:

fuelBar->setPercentage(80); // Value between 0-100

That’s it. We have learned how to build and use an progress bar to display some numerical value (ie fuel consumption). Any question, just leave a comment 🙂

void CCProgressTimerMulti::addState (const float _lowerLimit, const float _upperLimit,const string _spriteName,const int _alpha)
{
        // State initialization
       ProgressStates temp = ProgressStates();
       temp.lowerLimit = _lowerLimit;
       temp.upperLimit = _upperLimit;
       temp.m_stateSprite = CCSprite::createWithSpriteFrameName (_spriteName.c_str());
       temp.m_stateSprite->setOpacity(_alpha);
       
        // First state added to this control, will be always the default current state
        if (currState == -1)
       {
              currState  = 0;
              currLowerLimit = _lowerLimit;
              currUpperLimit = _upperLimit;
              this->initWithSprite(CCSprite::createWithSpriteFrameName (_spriteName.c_str()));           
       }      

        // Add the state to our states list
       m_states->insert(make_pair(m_states->size(),temp));
}

Leave a Reply