首先对于学习Cocos2D来说我是一个新手,尽管我之前学过Windows编程,DirectX,QT(实习的时候做过)。从今天开始我会将我对于Cocos2d-x的理解发在博客里。废话不多说,开始进入正题。
我在大学里主要学习的是C++,所以Cocos2D-X作为我的首选,Cocos2D-X的版本我选的是3.13.1。在设置好各种环境变量和参数后我成功运行了系统自带的模板,在查看文件的过程中我对Cocos2D-x的代码执行顺序产生的好奇,所以便开始探寻。
众所周知,程序的起始点都是main函数,我找到系统生成的main.cpp文件发现里面就几行代码,如下:
USING_NS_CC; int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // create the application instance AppDelegate app; return Application::getInstance()->run(); } |
USING_NS_CC:就是使用Cocos2d自己的命名空间,在vs2015中“转到定义”便可查看。
WinMain:这个函数只要学习过Windows编程的人都知道,这里不详细说。
WinMain函数中的两个宏定义我们不必管,就当传递参数就行了。接下来两行才是让我深入思考的地方。
AppDelegate app:这个系统有注释,说是应用程序的实例(我更喜欢理解为句柄)。
接下来就是让我不解的地方,这个app对象为什么没有去调用相应的方法呢而且我把这一行删除了编译时会报错(我以为会跟QT一样删除了不会报错)。于是我先去了AppDelegate这个类查看(delegate是代表的意思,所以这个类是APP的代表),在这个类中只有3个方法(析构,构造除外),这3个方法相信大家都知道。除此之外并没有什么特别的,我想了半天终于明白了,这个类是继承于cocos2d::Application这个类的,在继承中基类的构造函数早于子类构造函数被创建,所以在app这个对象被创建出来之前,父类的构造函数已经执行了一遍了(哇,考试的时候这种问题很简单,但到了实践又忘了),所以我进入了cocos2d::Application这个类里面,它的构造函数如下:
Application::Application() : _instance(nullptr) , _accelTable(nullptr) { _instance = GetModuleHandle(nullptr); _animationInterval.QuadPart = 0; CC_ASSERT(! sm_pSharedApplication); sm_pSharedApplication = this; } |
这里面最重要的是最后一行sm_pSharedApplication = this,将this指针赋予了sm_pSharedApplication。sm_pSharedApplication这个变量是一个静态变量,就表明所有对象共享一份。现在就没这个构造函数啥事了,然后我们在回到WinMain函数中。
在函数最后一行为:return Application::getInstance()->run(),跟我们在平时的编程中看到的不太一样,我们看见的都是return 0,其实run这个函数返回的就是int值,我们可以转到函数里面去看下。现在我们看下这个语句的前半段,Application::getInstance(),我们一眼就能看出这是一个静态函数,我们进入函数内部查看,发现只有如下几行:
Application* Application::getInstance() { CC_ASSERT(sm_pSharedApplication); return sm_pSharedApplication; } |
sm_pSharedApplication,这个变量怎么这么眼熟啊,对了,就是在之前的构造函数中已经被赋值的变量,这个时候它有了指向Application的指针(其实从返回值中就可以看出来了只是不知道在什么时候被赋值了),返回了Apllication指针后便调用run()方法,这个方法就不详细说了,但是在这个方法中调用了applicationDidFinishLaunching()方法,这个方法是一个纯虚函数,它在AppDelegate类中被实现了,所以调用的是AppDelegate类中的方法(纯虚函数我没有去查看它的用法),所有一切都说的通了。
另外,之所以Cocos2D-X中有那么多虚函数,就是为了实现多态,据我目前的了解,我们使用的指针是Application类的,要用它去执行相应的方法,就必须将相应函数设置为虚函数。
这就是我第一天学习的理解,可能对于某些人来说比较简单吧。