0

我是 Cocos2D-X 的菜鸟,但我已经编程了很长时间......我想知道这段代码的意义是什么:

我的困惑主要在于这部分:

布尔 bRet = 假;做{}同时(0)

这是给出一些上下文的整个方法:

  bool GameScene::init()
    {
        CCLog("GameScene::init");
    bool bRet = false;
    do 
    {
        //////////////////////////////////////////////////////////////////////////
        // super init first
        //////////////////////////////////////////////////////////////////////////
        CC_BREAK_IF(! CCLayer::init());

            // Initialize the parent - gets the sprite sheet loaded, sets the background and inits the clouds
            MainScene::init();

            // Start off as game suspended
            gameSuspended = true;

            // Get the bird sprite
            CCSprite *bird = CCSprite::createWithSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("bird.png"));
            this->addChild(bird, 4, kBird);

            // Initialize the platforms
            initPlatforms();

            // Create the bonus sprite
            CCSprite *bonus;

            // Load in the bonus images, 5, 10, 50, 100
            for(int i=0; i<kNumBonuses; i++) 
            {
                    bonus = CCSprite::createWithSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(bonus_image[i]));
                    this->addChild(bonus,4, kBonusStartTag+i);
                    bonus->setVisible(false);
            }

            // Create the Score Label
            CCLabelBMFont* scoreLabel = CCLabelBMFont::labelWithString("0",  "Images/bitmapFont.fnt");
            this->addChild(scoreLabel, 5, kScoreLabel);

            // Center the label
            scoreLabel->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width/2,CCDirector::sharedDirector()->getWinSize().height - 50));

            // Start the GameScene stepping
            schedule(schedule_selector(GameScene::step));

            // Enable the touch events
            setTouchEnabled(true);
            // Enable accelerometer events
            setAccelerometerEnabled(true);

            // Start the game
            startGame();

    bRet = true;
} while (0);

return bRet;
}

此代码来自:https ://code.google.com/p/tweejump-cocos2dx/source/browse/trunk/Classes/GameScene.cpp

这是一款开源游戏。

我知道 bRet 代表布尔返回值,但我对一些事情感到困惑......我对此感到困惑的一个原因是为什么还要像这样的程序?其次,当 bRet == false 是否等于 0 时,while 循环如何知道......我错过了什么吗?

我的另一个问题是你怎么知道何时使用语法 CCdataType* varName = ..., vs. CCdataType *pVarName = ... 我知道第二个是指针,但也许我错过了一些东西......我不明白其中的区别。第一个是尊重声明吗?

4

3 回答 3

3

您的示例错过了解释一切的基本部分 - 代码中的真正逻辑。我不是 Cocos 方面的专家,但据我所知,它通常是这样使用的:

bool bRet = false;
do 
{
    CC_BREAK_IF(!conditionA); // same as  if (!conditionA) break;
    ... some code which possibly sets bRet
    CC_BREAK_IF(!conditionB);        
    ... some other code which possibly sets bRet
    CC_BREAK_IF(!conditionC);        
    ... some other code which possibly sets bRet
    bRet = true;
} while (0);
return bRet;

在这种情况下,它允许代码跳转到 return 语句,而无需求助于goto,或嵌套一堆if语句。将其与此进行比较:

bool bRet = false;
if (conditionA); 
{
    ... some code which possibly sets bRet
    if (conditionB)
    {
        ... some other code which possibly sets bRet
        if (conditionC);        
        {
            ... some other code which possibly sets bRet
        }
    }
}
bRet = true;

return bRet;
于 2013-03-11T23:52:39.743 回答
2

在 Cocos2d-x 论坛上找到了理由

以前,Cocos2d-x 的开发人员编写了管理它的代码,使用 s 进行清理goto

#define check(ret)  if(!ret) goto cleanup;

void func()
{
  bool bRet = false;

  bRet = doSomething();
  check(bRet);
  bRet = doSomethingElse();
  check(bRet);

  bRet = true;

cleanup:
  // Do clean up here

  return bRet;
}

如您所见,如果在此过程中出现任何问题,这是在函数末尾跳转到清理的一种非常讨厌的方式。对函数的每次调用都会返回是否成功。然后check宏用于查看是否bRet为真,如果不是,则直接跳转到cleanup标签。

然后他决定把 s 去掉,goto改成breakfromdo while循环:

#define CC_BREAK_IF(cond)  if(!cond) break;

void func()
{
  bool bRet = false;

  do {
    bRet = doSomething();
    CC_BREAK_IF(bRet);
    bRet = doSomethingElse();
    CC_BREAK_IF(bRet);

    bRet = true;
  } while (0);

  // Do clean up here

  return bRet;
}

这具有完全相同的效果。它只是break用作一种在循环goto后跳转到代码的机制。do while

于 2013-03-11T23:59:16.553 回答
1

没有意义,这只是糟糕的风格。整个方法可以(并且应该)重写为:

bool GameScene::init()
{
    CCLog("GameScene::init");

    if (!CCLayer::init())
        return false;

    // Initialize the parent - gets the sprite sheet loaded, sets the background and inits the clouds
    MainScene::init();

    // … lots of scene setup code here ...

    return true;
}

我已经看到引擎运行其主循环的类似代码,但在这种情况下,它将是一个无限循环:

do
{
    // run game loop as fast as it can

    // end the game
    if (userQuits)
        break;
} while(true);

即使您需要额外的范围,例如为了避免局部变量的名称冲突,一对额外的大括号就足够了。像这样:

{
    int x = 10;
    // do stuff
}
{
    int x = 234; // this x is in its own scope
    // do other stuff
}
于 2013-03-12T00:06:53.533 回答