结合一些游戏调试常用的技巧来分析Cocos2d-x程序的生命周期。
再次打开“AppDelegate.cpp”文件。为了清楚地理解函数间的调用关系,不妨给每个函数的开头加上一个日志函数调用,在控制台打印该函数被调用的信息。因此,我们建立下面的一个日志类,利用临时变量在栈中的生命周期,搭配自动构造和析构函数产生的日志,并定义一个宏来跟踪函数名称,使用它们来打印函数的开始和结束。
新建的类文件LifeCircleLogger.h要和AppDelegate.cpp在同一个文件夹,否则上面的语句会报打不开文件的错。在LifeCircleLogger.h中添加如下代码:
//引用string类型
#include<string>
//#include"cocos2d.h"和USING_NS_CC实现CCLog函数的调用。
#include"cocos2d.h"
//引用string类型
USING_NS_CC;
using namespace std;
class LifeCircleLogger{
string m_msg;
public:
LifeCircleLogger(){}
LifeCircleLogger(const string& msg):m_msg(msg){
CCLog("%s BEGINS!",m_msg.c_str());}
~LifeCircleLogger(){CCLog("%s ENDS!",m_msg.c_str());}
};
//__FUNCTION__可以获得当前执行的函数的名字,c_str()是返回指向字符串的指针。
#define LOG_FUNCTION_LIFE LifeCircleLogger(_FUNCTION_);
这里出现的CCLog是Cocos2d-x的控制台输出函数,其参数方式与C语言的printf完全一致,用%d表示整型,%s表示字符串等。实际上,在Windows平台上,该函数正是通过包装printf函数实现的。在iOS和Android等平台上,这个函数有着同样的接口表示,并都可以在调试时打印信息到控制台。
我们在AppDelegate类中所有函数的第一条语句前加入LOG_FUNCTION_LIFE宏:
当然首先在AppDelegate.cpp 里要添加 #include "LifeCircleLogger.h"
AppDelegate::AppDelegate()
{
LOG_FUNCTION_LIFE
}
AppDelegate::~AppDelegate()
{
LOG_FUNCTION_LIFE
SimpleAudioEngine::end();
}
bool AppDelegate::applicationDidFinishLaunching()
{
LOG_FUNCTION_LIFE
// initializedirector
CCDirector *pDirector =CCDirector::sharedDirector();
//pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView());
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
// turn ondisplay FPS
pDirector->setDisplayStats(true);
// set FPS. thedefault value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 /60);
// create ascene. it's an autorelease object
CCScene *pScene = HelloWorld::scene();
// run
pDirector->runWithScene(pScene);
return true;
}
// Thisfunction will be called when the app is inactive. When comes a phone call,it'sbe invoked too
void AppDelegate::applicationDidEnterBackground()
{
LOG_FUNCTION_LIFE
CCDirector::sharedDirector()->stopAnimation();
SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}
// thisfunction will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
LOG_FUNCTION_LIFE
CCDirector::sharedDirector()->startAnimation();
SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}
启动游戏,然后操作如下:首先把游戏最小化,然后再把它恢复到前台,最后关闭游戏。完成后回到VS,可以在控制台中看到函数调用顺序。
由此可知,AppDelegate是整个程序的入口。实际上,AppDelegate处理了程序生命周期中的4个重要事件点:程序完成初始化,程序进入后台,程序重回前台和程序结束退出。进入后台和重回前台两个函数完成暂停和恢复游戏的处理。appDidFinishingLaunching则完成了加载游戏场景等工作。