我的Cocos2d-x学习笔记(一)Windows下程序如何开始运行

    现在开始学习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运行起来了!




原文地址:https://www.cnblogs.com/gongyan/p/4539412.html