我是Cocos2D-X的菜鸟,但我已经编程了很长时间......我想知道这段代码的重点是什么:
我的困惑主要在于这部分:
bool bRet = false; 做 {} while(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代表bool返回值,但是我对一些事情感到困惑...我对此感到困惑的一个原因是为什么即使是这样的程序呢?其次,如果bRet == false,while循环如何知道它是否等于0 ...我错过了什么?
我的另一个问题是你怎么知道何时使用语法CCdataType * varName = ...,vs。CCdataType * pVarName = ...我知道第二个是指针,但也许我错过了什么......我不明白其中的区别。是第一个尊重声明?
答案 0 :(得分: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;
答案 1 :(得分:2)
我找到了the rationale on the Cocos2d-x forum。
以前,Cocos2d-x的开发人员使用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
标签。
然后他决定摆脱goto
并将其从break
循环更改为do 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
循环后跳转到代码。
答案 2 :(得分: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
}