重新学习COCOs2D-X版本2.2.3开始---第一篇引擎的游戏入口


你看很多视频,很多教程,很多人会告诉你,cocos2dx引擎的游戏入口都是从如下代码开始

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);

    // create a scene. it's an autorelease object
    CCScene *pScene = HelloWorld::scene();

    // run
    pDirector->runWithScene(pScene);

    return true;
}


但一个好奇心强大的人只知道这个是远远不够的,可能很少人会告诉你为什么是从这里开始呢。

现在跟着问题一步步回溯,我们就回到C++程序的起点,也就是mian函数

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR    lpCmdLine,int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // create the application instance
    AppDelegate app;
    CCEGLView* eglView = CCEGLView::sharedOpenGLView();
    eglView->setViewName("Test");
    eglView->setFrameSize(480,320);
    return CCApplication::sharedApplication()->run();
}

从该代码大家可以发现一开始顶一个一个AppDelegate app 之后都没见用过,有经验的人可能会发现这个类的名字,同过名字可以看出,这是设计模式之中的代理模式,并且也是C++种的多态特性。

这个问题我们先不管,就当做问号放在这,现在我们要关系的是 最后一句话,CCApplication::sharedApplication()->run();

我们对着run()一直按F12你就会路过

int CCApplication::run()
{
    //此处略去代码

    // Initialize instance and cocos2d.
    if (!applicationDidFinishLaunching())
    {
        return 0;
    }

  //此处略去代码
}
接下来你在进入applicationDidFinishLaunching()你会发现如下
bool AppDelegate::applicationDidFinishLaunching() {
   //此处略去代码
    return true;
}

是不是很熟悉也就是游戏的入口,但是你会发现该函数是AppDelegate的成员,然而并不是CCApplication的成员,但为什么CCApplication可以直接调用呢,有人会说是继承的关系,没错他继承了CCApplicationProtocol,看看CCApplicationProtocol的定义

class CC_DLL CCApplicationProtocol
{
public:

    //略去一部分代码
   /**
    @brief    Implement CCDirector and CCScene init code here.
    @return true    Initialize success,app continue.
    @return false   Initialize Failed,app terminate.
    */
    virtual bool applicationDidFinishLaunching() = 0;

};

// end of platform group
/// @}

NS_CC_END

#endif    // __CC_APPLICATION_PROTOCOL_H__

这里声明该方法。也就是说有这么一个继承体系

CCApplicationProtocol->CCApplication->AppDelegate

而且三个类中只有AppDelegate中的applicationDidFinishLaunching定义了,其他里面也只有声明而已。但是我们还没解决为什么

CCApplication::sharedApplication()->run();中里面的applicationDidFinishLaunching会是AppDelegate里面的,而不是CCApplication。

这里有一段CCApplication.cpp代码如下

<pre name="code" class="cpp">CCApplication * CCApplication::sm_pSharedApplication = 0;

CCApplication::CCApplication()
: m_hInstance(NULL),m_hAccelTable(NULL)
{
    m_hInstance    = GetModuleHandle(NULL);
    m_nAnimationInterval.QuadPart = 0;
    CC_ASSERT(! sm_pSharedApplication);
    sm_pSharedApplication = this;
}


 

这里面的sm_pSharedApplication = this,中的this是整个问题的关键,一般人直接看可能会觉得this指的是当前类的实例也就是CCApplication。其实并不是这样的,这里的this是指AppDelegate,所以最后调用的applicationDidFinishLaunching是AppDelegate中的

更贴切的来说是AppDelegate app这句话调用的时候,初始化了构造函数,进而调用父类的构造函数,所以此时的this的调用者本身,也就是AppDelegate

下列是为什么方便理解所写得简化版

/*
 * CCApplicationProtocol.h
 *
 */

#ifndef SRC_CCAPPLICATIONPROTOCOL_H_
#define SRC_CCAPPLICATIONPROTOCOL_H_

class CCApplicationProtocol {
public:
	CCApplicationProtocol();
	virtual ~CCApplicationProtocol();

	virtual bool applicationDidFinishLaunching()=0;
};

#endif /* SRC_CCAPPLICATIONPROTOCOL_H_ */


/*
 * CCApplication.h
 *
 */

#ifndef CCAPPLICATION_H_
#define CCAPPLICATION_H_

#include "CCApplicationProtocol.h"

class CCApplication: public CCApplicationProtocol {
public:
	CCApplication();
	virtual ~CCApplication();

	int run();

	static CCApplication * sharedApplication();
	static CCApplication * sm_pSharedApplication;
};

#endif /* CCAPPLICATION_H_ */


#include "CCApplication.h"
#include "stddef.h"

CCApplication * CCApplication::sm_pSharedApplication = NULL;

CCApplication::CCApplication() {
	// TODO Auto-generated constructor stub
	sm_pSharedApplication = this;
}

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


int CCApplication::run(){
	applicationDidFinishLaunching();
	return 1;
}

CCApplication * CCApplication::sharedApplication()
{
	if(sm_pSharedApplication != NULL)
		return sm_pSharedApplication;
}



/*
 * main.cpp
 *
 */



#include <iostream>
#include "CCApplication.h"
#include "AppDelegate.h"
using namespace std;
int main()
{
	AppDelegate app;

	//AppDelegate * pp = &app;

//	CCApplication * p = &app;
//	p->applicationDidFinishLaunching();

	return CCApplication::sharedApplication()->run();
}


最后输出结果是Game start

相关文章

操作步骤 1、创建cocos2d-x工程 2、新建 Scene1.cpp Scene1.h Scene1.h代码 #ifndef __SCENE1_H__#defi...
开发环境:OS(WINDOWS 8.1 X64 企业版) cocos2d-x 2.2.1 vs2010 想给vs安装上cocos的模版,执行Install...
把创建项目做成一个批处理,当创建项目时可以省时省力很多。 操作步骤 1、在 E:cocos2d-x-2.2.1toolspr...
https://www.cnblogs.com/JiaoQing/p/3906780.html 四个响应函数 1 EventListenerPhysicsContact* evC...
转载于 http://www.cnblogs.com/kenkofox/p/3926797.html 熟悉js的dom事件或者flash事件的,基本都能立...
ScrollView(滚动容器)加载大量item时会导致游戏界面的卡顿,严重时整个界面会出现卡死的情况。最近项...