Cocos2d-x basics

Some articles about Cocos2d-x framework

Advanced usage of CC_CALLBACK

Posted at — Sep 25, 2020

In the previous article about callbacks I’ve said that the number in the CC_CALLBACK_* macro means the amount of parameters need for called function. That wasn’t exactly true because the C++ magic allows to do a one more trick here.

Let’s look again the green UFO from this article. The only difference between moving to the right and moving to the left is the coordinate of destination point. Obviously, it would be better to process both movements with the same method; if only we could call this method with different parameters.

The trick is that the CC_CALLBACK_ macro can receive any amount of parameters. The std::bind will transfer all the parameters to the called function.

Here is the example. The common callback for the button pressing is declared like this:

class ActionsDemoScene : public cocos2d::Scene {
public:
  // .....
protected:
  void ufoMoveCallback(cocos2d::Ref *pSender, const int direction);
};

Here direction is the additional parameter we would like to transfer to called function.

And here is the CC_CALLBACK_1 usage:

MenuItemImage* leftButton = MenuItemImage::create(
    "ui/leftArrow1.png", "ui/leftArrow2.png",
    CC_CALLBACK_1(ActionsDemoScene::ufoMoveCallback, this, GU_MOVE_LEFT));

MenuItemImage* rightButton = MenuItemImage::create(
  "ui/rightArrow1.png", "ui/rightArrow2.png",
  CC_CALLBACK_1(ActionsDemoScene::ufoMoveCallback, this, GU_MOVE_RIGHT));

Here GU_MOVE_LEFT and GU_MOVE_RIGHT are the constant values to differ between movement directions.

So, the common callback will be implemented like:

void ActionsDemoScene::ufoMoveCallback(Ref *pSender, const int direction) {
  float newX = 0; //undefided at this point
  if (direction == GU_MOVE_RIGHT) {
    newX = rightX;
  }
  else {
    newX = leftX;
  }

  // use the newX value
}

Also, we could do one more step and provide the new coordinate value right to CC_CALLBACK_1 instead of the special constant values. Then we could get rid of if in the method implementation. However, I thought it would make the code less readable.