由于ccLayer->时间表,Cocos2d-x崩溃(schedule_selector(…),…);

时间:2022-04-07 14:35:47

I have Android development background. A few days ago, I started to learn Cocos2d-x for game development. I was creating a simple splash screen and some menu screen but got stuck on some app crash issue. I want Splash Scene to stay for 3 seconds and to load MenuScene after that. So I tried to use schedule method to replace the scenes. But I am getting crash when it comes to execute the scheduled task. Here are my simple classes;

我有Android开发背景。几天前,我开始学习Cocos2d-x游戏开发。我创建了一个简单的闪屏和一些菜单屏幕,但在一些应用程序崩溃问题上卡住了。我想让飞溅场景停留3秒,然后在那之后加载MenuScene。所以我尝试使用schedule方法来替换场景。但是,在执行预定任务时,我正在崩溃。这是我简单的课程;

Splash.h class:

飞溅。h类:

#ifndef SPLASHSCREEN_H_
#define SPLASHSCREEN_H_

#include <layers_scenes_transitions_nodes/CCLayer.h>
#include <cocos2d.h>

/**
 * Splash Screen for the game
 *
 */

USING_NS_CC;

class SplashScreen: public cocos2d::CCLayer {
public:
    SplashScreen();
    virtual ~SplashScreen();
    virtual bool init();
    static cocos2d::CCScene* newInstance();
    void endSplash(float dt);

    // implement the "static node()" method manually
    CREATE_FUNC(SplashScreen);


};

#endif

SplashScreen.cpp:

SplashScreen.cpp:

    #define COCOS2D_DEBUG 1

#include "SplashScreen.h"
#include "GeneralMenuScreen.h"


USING_NS_CC;

SplashScreen::SplashScreen() {
    // TODO Auto-generated constructor stub

}

SplashScreen::~SplashScreen() {
    // TODO Auto-generated destructor stub
}

bool SplashScreen::init() {

    if(! CCLayer::init() ) {
        return false;
    }
    CCSize windowSize = CCDirector::sharedDirector()->getVisibleSize();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

    CCSprite* background = CCSprite::create("background.png");
    background->setPosition(ccp(origin.x + windowSize.width/2, origin.y + windowSize.height/2));
    this->addChild(background);

    CCLabelTTF* loadingText = CCLabelTTF::create("Loading...", "Arial", 36);
    loadingText->setAnchorPoint(ccp(0,0));
    loadingText->setPosition(ccp(origin.x + windowSize.width/2 - loadingText->getContentSize().width/2, origin.y + windowSize.height/2 - loadingText->getContentSize().height/2));
    this->addChild(loadingText);

    /*  this->schedule(schedule_selector(SplashScreen::endSplash), 5.0);        */
CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(SplashScreen::endSplash), this , 5, false, 0, 0 );

/*   CCTimer* ccTimer = CCTimer::timerWithTarget(this, schedule_selector(SplashScreen::endSplash), 5.0f);
ccTimer->update(1.0);       */


/* CCDelayTime* startDelay = CCDelayTime::create(5.0);
CCCallFunc *showHearts = CCCallFunc::create(this, callfunc_selector(SplashScreen::endSplash));
CCSequence* seq = CCSequence::create(startDelay, showHearts);
background->runAction(seq);*/

    return true;

}


CCScene* SplashScreen::newInstance() {

    // 'scene' is an autorelease object
    CCScene* scene = CCScene::create();

    // 'layer' is an autorelease object
    SplashScreen* splashScreen = SplashScreen::create();

    scene->addChild(splashScreen);

    return scene;

}

void SplashScreen::endSplash(float dt) {

    //CCLOG("FilePath = %f", dt);
    CCScene* menuScreen = GeneralMenuScreen::newInstance();
    CCDirector::sharedDirector()->replaceScene(menuScreen);

}

GeneralMenuScreen.cpp:

GeneralMenuScreen.cpp:

#include "GeneralMenuScreen.h"

USING_NS_CC;

GeneralMenuScreen::GeneralMenuScreen() {

}

GeneralMenuScreen::~GeneralMenuScreen() {

}

CCScene* GeneralMenuScreen::newInstance() {

    CCScene* scene = CCScene::create();
    GeneralMenuScreen* layer = GeneralMenuScreen::create();
    scene->addChild(layer);

    return scene;

}

bool GeneralMenuScreen::init() {

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

    CCSize windowSize = CCDirector::sharedDirector()->getVisibleSize();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

    CCSprite* background = CCSprite::create("background.png");
    background->setPosition(ccp(origin.x + windowSize.width/2, origin.y + windowSize.height/2));
    this->addChild(background);

    int margin = 10;

    CCLabelTTF* playLabel = CCLabelTTF::create("PLAY", "Arial", 36);
    CCMenuItemLabel* menuPlay = CCMenuItemLabel::create(playLabel);
    menuPlay->setPosition(origin.x + windowSize.width/2 - menuPlay->getContentSize().width/2, origin.y + windowSize.height/2 + menuPlay->getContentSize().height + margin/2 );

    CCMenu* menu = CCMenu::create(menuPlay);
    menu->setPosition(CCPointZero);
    this->addChild(menu);


    return true;


}

The splash screen runs but after 3 secods, the endSplash method is not being called and app crashed. I have never programmed in C/C++. Any idea where I am going wrong? And also, is there any way to debug the cocos2d-x apps using some debugger like we have in android/ios?

闪屏运行,但在3个secods之后,endSplash方法没有被调用,app崩溃。我从未用C/ c++编程。知道我哪里出错了吗?还有,有没有什么方法可以用我们在android/ios中使用的调试器来调试cocos2d-x应用程序?

4 个解决方案

#1


0  

You can use gdb for debugging.

您可以使用gdb进行调试。

What are you writing those getInstance methods for? Pair of create + init should suffice in most cases.

你为什么要写这些getInstance的方法呢?在大多数情况下,对create + init应该足够了。

Maybe try using CCDirector::sharedDirector()->getScheduler()->scheduleSelector or just run action calling some method on your object: http://www.cocos2d-x.org/reference/native-cpp/V3.0alpha0/d3/d32/classcocos2d_1_1_call_func.html . It is easier to manager actions running on your objects than to deal with a scheduler IMO.

可能尝试使用CCDirector::sharedDirector()->getScheduler()->调度器,或者只是在你的对象上运行调用某个方法:http://www.cocos2d- x.org/reference/naticpp/v3.0alpha0/d3/d32/classcocos2d_1_call_func.html。管理对象上运行的操作要比处理调度程序更容易。

When having such errors you may want to try placing some asserts checking if objects aren't dead (check if not nullptr and retaincount). And off course run it with debugger to see where the explosion happens. Right now I cannot find errors in your code, I'll try to run it later at home.

当有这样的错误时,您可能想尝试放置一些断言检查对象是否已死(检查是否为nullptr和retaincount)。然后用调试器运行它,看看爆炸发生的地方。现在我在你的代码中找不到错误,我将尝试在家里运行它。

#2


0  

So after a little investigation:

所以经过一番调查:

  • constructor of a CCObject should be private (read as: pretty much always must be)
  • CCObject的构造函数应该是私有的。
  • in CCObject.h it is a good idea to replace defualt c-like castring with static_cast --> you'll avoid many hours of debugging selectors
  • 在CCObject。用static_cast代替defualt c-like castring是一个好主意——>可以避免许多小时的调试选择器。
  • your code works for me under VC12 (but I used pushScene instead of replaceScene) --> are you using master branch of cocos?
  • 您的代码在VC12下为我工作(但我使用的是pushScene而不是replaceScene)——>是您使用cocos的主分支吗?

#3


0  

Instead of this...

而不是这个……

CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(SplashScreen::endSplash), this , 5, false, 0, 0 );

Try this..

试试这个. .

this->scheduleOnce(schedule_selector(SplashScreen::endSplash),delayTime);

where delayTime =3 or anything.

delayTime =3或任何东西。

#4


0  

Use this it will work for you

用这个就行了。

schedule(SEL_SCHEDULE(&SplashScreen::endSplash), 5);

#1


0  

You can use gdb for debugging.

您可以使用gdb进行调试。

What are you writing those getInstance methods for? Pair of create + init should suffice in most cases.

你为什么要写这些getInstance的方法呢?在大多数情况下,对create + init应该足够了。

Maybe try using CCDirector::sharedDirector()->getScheduler()->scheduleSelector or just run action calling some method on your object: http://www.cocos2d-x.org/reference/native-cpp/V3.0alpha0/d3/d32/classcocos2d_1_1_call_func.html . It is easier to manager actions running on your objects than to deal with a scheduler IMO.

可能尝试使用CCDirector::sharedDirector()->getScheduler()->调度器,或者只是在你的对象上运行调用某个方法:http://www.cocos2d- x.org/reference/naticpp/v3.0alpha0/d3/d32/classcocos2d_1_call_func.html。管理对象上运行的操作要比处理调度程序更容易。

When having such errors you may want to try placing some asserts checking if objects aren't dead (check if not nullptr and retaincount). And off course run it with debugger to see where the explosion happens. Right now I cannot find errors in your code, I'll try to run it later at home.

当有这样的错误时,您可能想尝试放置一些断言检查对象是否已死(检查是否为nullptr和retaincount)。然后用调试器运行它,看看爆炸发生的地方。现在我在你的代码中找不到错误,我将尝试在家里运行它。

#2


0  

So after a little investigation:

所以经过一番调查:

  • constructor of a CCObject should be private (read as: pretty much always must be)
  • CCObject的构造函数应该是私有的。
  • in CCObject.h it is a good idea to replace defualt c-like castring with static_cast --> you'll avoid many hours of debugging selectors
  • 在CCObject。用static_cast代替defualt c-like castring是一个好主意——>可以避免许多小时的调试选择器。
  • your code works for me under VC12 (but I used pushScene instead of replaceScene) --> are you using master branch of cocos?
  • 您的代码在VC12下为我工作(但我使用的是pushScene而不是replaceScene)——>是您使用cocos的主分支吗?

#3


0  

Instead of this...

而不是这个……

CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(SplashScreen::endSplash), this , 5, false, 0, 0 );

Try this..

试试这个. .

this->scheduleOnce(schedule_selector(SplashScreen::endSplash),delayTime);

where delayTime =3 or anything.

delayTime =3或任何东西。

#4


0  

Use this it will work for you

用这个就行了。

schedule(SEL_SCHEDULE(&SplashScreen::endSplash), 5);