现在开始学习Cocos2d-x开发手机游戏,做这个笔记记录学习中的一些收获,同时利于复习。利用的Cocos2d-x2.2.6引擎。
每个程序都是有入口函数的,Cocos2d-x也不例外,在Windows下的VS开发环境中,入口函数在Win32筛选器下的main.cpp中。我们看一下main.cpp文件中内容。
#include "main.h"
首先包含了main.h头文件,头文件中包含了Win32编程的用到的windows.h和宽字符支持文件tchar.h;
还包含了CCStdC.h文件,cocos2d-x中c语言的头文件,其中包含了数学文件和网络支持,不继续深入研究了。
#include "AppDelegate.h"
包含了AppDelegate.h文件,这个文件是程序运行的关键。
#include "CCEGLView.h"
USING_NS_CC;
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// create the application instance
AppDelegate app;//创建一个AppDelegate对象
CCEGLView* eglView = CCEGLView::sharedOpenGLView();
eglView->setViewName("HelloWorld");
eglView->setFrameSize(480, 320);
return CCApplication::sharedApplication()->run();
}
上述代码中需要重点关注AppDelegate app;与CCApplication::sharedApplication()->run()这两行,CCApplication是程序中一个单例,在程序运行中只存在一个对象;CCApplication.cpp中部分代码如下:
CCApplication * CCApplication::sm_pSharedApplication = 0;
CCApplication* CCApplication::sharedApplication()
{
CC_ASSERT(sm_pSharedApplication);
return sm_pSharedApplication;
}
其中sm_pSharedApplication是一个CCApplication的对象指针,运行CCApplication::sharedApplication()返回当前这个单例对象的指针。而run()这个函数则是游戏开始运行的关键。重点关注CCApplication类成员函数run()中部分代码:
int CCApplication::run()
{
// Initialize instance and cocos2d.
if (!applicationDidFinishLaunching())
{
return 0;
}
applicationDidFinishLaunching()这个函数是CCApplication的父类中定义的纯虚函数,并且在CCApplication类中没用重写。这个函数是在AppDelegate中进行覆写了。
下面看看AppDelegate和CCApplication和CCApplicationProtocol之间的关系。
class AppDelegate : private cocos2d::CCApplication
class CC_DLL CCApplication : public CCApplicationProtocol
由上诉代码可以看出类AppDelegate继承自CCApplication,而CCApplication继承自CCApplicationProtocol。
而类CCApplication是一个单例对象,在main.cpp中CCApplication::sharedApplication()->run()可见它已经被初始化,那么它是在哪里初始化的呢?
这时候回来看AppDelegate app,在AppDelegate 初始化app时候,会先调用父类的构造函数,CCApplicationProtocol的构造函数是空函数,然后CCApplication构造函数执行,CCApplication构造函数代码如下:
CCApplication::CCApplication()
: m_hInstance(NULL)
, m_hAccelTable(NULL)
{
m_hInstance = GetModuleHandle(NULL);
m_nAnimationInterval.QuadPart = 0;
CC_ASSERT(! sm_pSharedApplication);
sm_pSharedApplication = this;
}
在CCApplication::CCApplication()中我们可以看到CCApplication对象指针sm_pSharedApplication赋值为this,也就是AppDelegate app。
所以CCApplication单例对象在子类AppDelegate定义app时候,通过调用首先执行父类CCApplication构造函数时候被初始化。
知道了CCApplication什么时候被初始化后,再继续看看程序如何被运行,上面提到的CCApplication类成员函数run()中部分代码,
applicationDidFinishLaunching()这个函数是CCApplication的父类中定义的纯虚函数,并且在CCApplication类中没用重写,是在AppDelegate中进行覆写。
其中applicationDidFinishLaunching()则是程序运行的关键点!AppDelegate中代码如下:
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
CCDirector* pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
pDirector->setOpenGLView(pEGLView);
// turn on display FPS
pDirector->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
CCScene *pScene = HelloWorld::scene();
// run
pDirector->runWithScene(pScene);
return true;
}
CCApplication中的run()函数调用了其子类AppDelegate具体实现后的applicationDidFinishLaunching()函数,applicationDidFinishLaunching()中开始运行游戏程序。
CCScene* pScene = HelloWorld::scene()获取一个HelloWorld的场景,并且通过pDirector->runWithScene(pScene)运行此场景。到此为止,HelloWorld运行起来了!