0

私は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の戻り値を表すことは理解していますが、いくつかの点で混乱しています...これに混乱している理由の1つは、このようなプログラムでさえあるのはなぜですか。次に、whileループは、bRet == falseが0に等しい場合、どのようにしてそれを知るのでしょうか...何かが足りないのでしょうか。

私の他の質問は、CCdataType * varName = ...と、CCdataType * pVarName = ...の構文をいつ使用するかをどのように知るかです。2番目の質問はポインターですが、何かが足りない可能性があります...違いがわかりません。最初のものは服従声明ですか?

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;

この場合、コードは、に頼っgotoたり、一連のステートメントをネストしたりすることなく、returnステートメントにジャンプできます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の開発者は、gotosでクリーンアップを管理するコードを作成しました。

#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マクロを使用してtrueかどうかを確認し、 trueでない場合は、ラベルbRetに直接ジャンプします。cleanup

次に、彼はsを取り除き、ループからgotoに変更することにしました。breakdo 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として使用するだけです。gotodo 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 に答える