Cocos2d-x初探
HelloWorld初探:
首选请看HelloWorld的main.cpp文件:
1 #include "main.h" 2 3 #include "../Classes/AppDelegate.h" 4 5 int APIENTRY _tWinMain(HINSTANCE hInstance, 6 HINSTANCE hPrevInstance, 7 LPTSTR lpCmdLine, 8 int nCmdShow) 9 { 10 UNREFERENCED_PARAMETER(hPrevInstance); 11 UNREFERENCED_PARAMETER(lpCmdLine); 12 13 // create the application instance 14 AppDelegate app; 15 16 return cocos2d::CCApplication::sharedApplication().run(); 17 }
有win32 api编程经验的都应该很容易看懂这段代码。UNREFERENCED_PARAMETER是一个宏,作用是防止编译器出现函数参数未被使用的warnning(自己查看,纯属个人yy)。
然后是定义了一个AppDelegate对象app,该类继承自CCApplication,CCApplication类的protected域定义了个CCApplication类型的指针,在CCApplication的构造函数里会赋值为this,然后静态成员函数sharedApplication返回该指针指向对象的引用,有点像使用了单例模式(或许其实就是单例)。
之后那句调用了app的run函数,进入整个程序的消息循环,run函数如下:
1 int CCApplication::run() 2 { 3 PVRFrameEnableControlWindow(false); //将窗口信息写入注册表之类,没有仔细研究 4 5 // Main message loop: 6 MSG msg; 7 LARGE_INTEGER nFreq; 8 LARGE_INTEGER nLast; 9 LARGE_INTEGER nNow; 10 11 //高精度时间计数 12 QueryPerformanceFrequency(&nFreq); //获得时钟频率 13 QueryPerformanceCounter(&nLast); //获取当前时钟精 14 15 //下面两个都是纯虚函数,子类实现,父类调用。 16 // Initialize instance and cocos2d. 17 if (! initInstance() || ! applicationDidFinishLaunching()) 18 { 19 return 0; 20 } 21 22 CCEGLView& mainWnd = CCEGLView::sharedOpenGLView(); 23 mainWnd.centerWindow(); 24 ShowWindow(mainWnd.getHWnd(), SW_SHOW); 25 26 while (1) 27 { 28 if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 29 { 30 // Get current time tick. 31 QueryPerformanceCounter(&nNow); 32 33 //m_nAnimationInterval保存了帧频率,可以通过CCDirector单例对象修改 34 // If it's the time to draw next frame, draw it, else sleep a while. 35 if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart) 36 { 37 nLast.QuadPart = nNow.QuadPart; 38 CCDirector::sharedDirector()->mainLoop(); 39 } 40 else 41 { 42 Sleep(0); 43 } 44 continue; 45 } 46 47 if (WM_QUIT == msg.message) 48 { 49 // Quit message loop. 50 break; 51 } 52 53 // Deal with windows message. 54 if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg)) 55 { 56 TranslateMessage(&msg); 57 DispatchMessage(&msg); 58 } 59 } 60 61 return (int) msg.wParam; 62 }
进入真正的消息循环的处理函数是CCDirector::sharedDirector()->mainLoop();
1 void CCDisplayLinkDirector::mainLoop(void) 2 { 3 if (m_bPurgeDirecotorInNextLoop) 4 { 5 purgeDirector(); //清除Director 6 m_bPurgeDirecotorInNextLoop = false; 7 } 8 else if (! m_bInvalid) 9 { 10 drawScene(); 11 12 // release the objects 13 CCPoolManager::getInstance()->pop(); 14 } 15 }
mainLoop是纯虚函数,这里由子类CCDisplayLinkDirector实现,并且为程序创建了其全局变量变量。
重点是drawScene(),这个函数里重绘所有的图形对象object。
这里要写一点,cocos2d里的所有object都是保存在一棵树结构里进行维护。重绘时,调用object的成员函数vist进行树的遍历。
每个结点都保存了zOrder的值(我们addObject时的第二个参数),每个结点的所有子结点都根据这个zOrder值进行排序,于是,遍历的顺序就改变了,重绘的次序也就改变了,这就是cocos2d处理层的方法。条理清晰,井井有序,啧啧...,以前碰到的一个引擎使用一个数组来保存所有的对象,然后再排序,这样的方法弱爆了。难以处理复杂的关系。
后来发现了篇很好的介绍cocos2d初始化的文章,懒得写了,直接上链接: