Добавление еще одного слоя на сцену в проекте HelloWorld

В проекте cocos2d-x HelloWorld я пытаюсь добавить еще один слой в сцену и сохранить ссылку на этот слой в члене данных. Поскольку функция HelloWorld::scene() является статической, я не могу добавить слой в эту функцию (поскольку я не могу установить элемент данных для слоя).

Поэтому я попытался получить сцену в функции init() следующим образом, однако это приводит к scene = 0x00000000.

Что я делаю неправильно?

bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {
        CC_BREAK_IF(! CCLayer::init());

        CCScene* scene = NULL;
        scene = CCDirector::sharedDirector()->getRunningScene();

        // add another layer
        HelloWorldHud* layerHud = HelloWorldHud::create();
        CC_BREAK_IF(! layerHud);
        // set data member
        this->layerHud = layerHud;

        // next line crashes (because scene  is 0x00000000)
        scene->addChild(layerHud);

    bRet = true;
    } while (0);
    return bRet;
}

PS: Причина, по которой я хочу добавить слой hud в сцену, а не в текущий слой, заключается в том, что я перемещаю текущий слой и не хочу, чтобы слой hud перемещался вместе с ним.


Изменить: поскольку принятый ответ допускал несколько вариантов, вот что я сделал, чтобы решить проблему:

1.) Удален слой HUD из функции init():

bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {
        CC_BREAK_IF(! CCLayer::init());

    bRet = true;
    } while (0);
    return bRet;
}

2.) И вместо этого добавил слой HUD в функцию сцены (что также сделано в cocos2d-iphone):

CCScene* HelloWorld::scene()
{
    CCScene * scene = NULL;
    do 
    {
        // scene
        scene = CCScene::create();
        CC_BREAK_IF(! scene);

        // HelloWorld layer
        HelloWorld *layer = HelloWorld::create();
        CC_BREAK_IF(! layer);
        scene->addChild(layer);

        // HUD layer
        HelloWorldHud* layerHud = HelloWorldHud::create();
        CC_BREAK_IF(! layerHud);
        scene->addChild(layerHud);

        // set data member
        layer->layerHud = layerHud;

    } while (0);

    // return the scene
    return scene;
}

По сути, проблема заключалась в том, что мое предположение «Поскольку функция HelloWorld::scene() является статической, я не могу добавить слой в эту функцию (поскольку я не могу установить элемент данных для слоя)» было неверным.


person Ben    schedule 24.08.2012    source источник


Ответы (1)


Сцена имеет значение NULL, потому что вы вызываете getRunningScene() еще до создания первой сцены.

И одно ваше предположение неверно. HelloWorld::scene() является статическим, но вы все равно можете добавить слой в эту функцию (и вы можете установить элемент данных для слоя)

правильный способ - создать новую публичную функцию

setLeyerHud(HelloWorldHud* hud);

в классе HelloWorld и в функции CCScene* HelloWorld::scene() добавьте следующие строки:

CCScene * scene = NULL;
do 
{
    // 'scene' is an autorelease object
    scene = CCScene::create();
    CC_BREAK_IF(! scene);

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();
    CC_BREAK_IF(! layer);

    HelloWorldHud* layerHud = HelloWorldHud::create();
    CC_BREAK_IF(! layerHud);

    scene->addChild(layer);

    scene->addChild(layerHud);

    layer->setLayerHud(layerHud);

} while (0);

это зависит от того, хотите ли вы добавить Hud в слой HelloWorld или добавить в сцену.

I. добавить новый слой в сцену:

удалить код

    CCScene* scene = NULL;
    scene = CCDirector::sharedDirector()->getRunningScene();

    // add another layer
    HelloWorldHud* layerHud = HelloWorldHud::create();
    CC_BREAK_IF(! layerHud);
    // set data member
    this->layerHud = layerHud;

    // next line crashes (because scene  is 0x00000000)
    scene->addChild(layerHud);

от

HelloWorld::init()

и изменить код в

CCScene* HelloWorld::scene()

to

CCScene * scene = NULL;
do 
{
    // 'scene' is an autorelease object
    scene = CCScene::create();
    CC_BREAK_IF(! scene);

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();
    CC_BREAK_IF(! layer);

    HelloWorldHud* layerHud = HelloWorldHud::create();
    CC_BREAK_IF(! layerHud);

    scene->addChild(layer);

    scene->addChild(layerHud);
} while (0);

// return the scene
return scene;

II. добавьте новый слой к слою HelloWorld:

изменить код

    CCScene* scene = NULL;
    scene = CCDirector::sharedDirector()->getRunningScene();

    // add another layer
    HelloWorldHud* layerHud = HelloWorldHud::create();
    CC_BREAK_IF(! layerHud);
    // set data member
    this->layerHud = layerHud;

    // next line crashes (because scene  is 0x00000000)
    scene->addChild(layerHud);

in

HelloWorld::init()

to

    // add another layer
    HelloWorldHud* layerHud = HelloWorldHud::create();
    CC_BREAK_IF(! layerHud);

    // next line crashes (because scene  is 0x00000000)
    this->addChild(layerHud);
person m.ding    schedule 26.08.2012
comment
Сцена создается в AppDelegate, а затем управляется режиссером. HelloWorld::init() вызывается из HelloWorld::scene(). Не могли бы вы объяснить, как я могу решить проблему? - person Ben; 27.08.2012
comment
@Ben: я отредактировал свой ответ, вы можете попробовать это. - person m.ding; 27.08.2012
comment
Спасибо, это действительно помогло. Вы правы, мое предположение было неверным. Я не мог использовать this->layerHUD в scene(), но мог использовать layer->layerHUD. Спасибо! :) - person Ben; 27.08.2012