cocos2d-x源码剖析之整体框架
2013-08-24 20:46
316 查看
刚阅读完了cocos2d-x的大部分源码,感觉受益匪浅,cocos2d-x的代码并不复杂,可读性很强,并且其中一部分精华的部分也可以运用到工作中去,相得益彰。现在看来,阅读源代码的最好方式是top-down的方式,先弄懂整个框架,再重点突破重要和感兴趣的模块。废话少说,先看看coscos2d-x的框架是怎样的,如何运行起来。
先让我们看看测试用例TestCpp中的主函数,也是整个Win32程序的入口。
先看看CCEGLView
CCEGLView是用来管理窗口和绘制。在 CCEGLView::Create中做了如下大家非常熟悉的事情
1. RegisterClass注册窗口,其中非常重要的消息处理函数CCEGLView::_WindowProc就是在整个地方定义的。整个游戏中的窗口的键盘、鼠标消息响应就可以在这个函数中进行处理。
2. initGL初始化OpenGL引擎.
再看看CCApplication
CCApplication是用来管理程序的逻辑,最后一句CCApplication::sharedApplication()->run()整个程序就开始高速运转起来了。刚开始看代码的时候有一个疑问:
1. 转发窗口消息,交给之前定义的CCEGLView::_WindowProc进行处理
2. 每隔m_nAnimationInterval.QuadPart时间,也就是游戏的一帧,进行一次处理.
这里就引出了最重要的一个类CCDirector即导演类,这个类也是一个单例,负责整个游戏场景管理,逻辑更新以及绘制。那让我们看看
CCDirector::sharedDirector()->mainLoop()的每帧的mainLoop都做了啥事情:
CCDirector的帧常工作:
读者仔细看看就会发现这个函数做了两个方面的工作,:
1. 更新调度器m_pScheduler,比如场景中的动作等,后面的博文会详细的分析
2. 绘制场景中的对象结点,树形的方式
至此,cocos2d-x的整体框架就非常清晰的摆在我们面前了,后面就开始解剖麻雀了^_^
先让我们看看测试用例TestCpp中的主函数,也是整个Win32程序的入口。
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("TestCpp"); eglView->setFrameSize(480, 320); return CCApplication::sharedApplication()->run(); }这个入口有2个非常重要的类CCEGLView和CCApplication,在整个程序中都是单例。
先看看CCEGLView
CCEGLView是用来管理窗口和绘制。在 CCEGLView::Create中做了如下大家非常熟悉的事情
1. RegisterClass注册窗口,其中非常重要的消息处理函数CCEGLView::_WindowProc就是在整个地方定义的。整个游戏中的窗口的键盘、鼠标消息响应就可以在这个函数中进行处理。
2. initGL初始化OpenGL引擎.
m_hDC = GetDC(m_hWnd); SetupPixelFormat(m_hDC); //SetupPalette(); m_hRC = wglCreateContext(m_hDC); wglMakeCurrent(m_hDC, m_hRC);CCEGLView::initGL中设置了像素的格式,创建了OpenGL的RenderContext,OpenGL最终渲染的结果会显示到该窗口的DC上。
再看看CCApplication
CCApplication是用来管理程序的逻辑,最后一句CCApplication::sharedApplication()->run()整个程序就开始高速运转起来了。刚开始看代码的时候有一个疑问:
CCApplication* CCApplication::sharedApplication() { CC_ASSERT(sm_pSharedApplication); return sm_pSharedApplication; }这个函数中的sm_pSharedApplication是在什么地方初始化的呢?聪明的你很快就会发现其实前面有一个AppDelegate app,AppDelegate是Application的子类,在这个子类的构造函数中声明了这个全局唯一的静态变量。
CCApplication::CCApplication() : m_hInstance(NULL) , m_hAccelTable(NULL) { m_hInstance = GetModuleHandle(NULL); m_nAnimationInterval.QuadPart = 0; CC_ASSERT(! sm_pSharedApplication); sm_pSharedApplication = this; }由此Application的单例也有了。Application::Run()做了什么呢,让整个程序运行起来了呢?
int CCApplication::run() { PVRFrameEnableControlWindow(false); // Main message loop: MSG msg; LARGE_INTEGER nFreq; LARGE_INTEGER nLast; LARGE_INTEGER nNow; QueryPerformanceFrequency(&nFreq); QueryPerformanceCounter(&nLast); // Initialize instance and cocos2d. if (!applicationDidFinishLaunching()) { return 0; } CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView(); pMainWnd->centerWindow(); ShowWindow(pMainWnd->getHWnd(), SW_SHOW); while (1) { if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // Get current time tick. QueryPerformanceCounter(&nNow); // If it's the time to draw next frame, draw it, else sleep a while. if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart) { nLast.QuadPart = nNow.QuadPart; CCDirector::sharedDirector()->mainLoop(); } else { Sleep(0); } continue; } if (WM_QUIT == msg.message) { // Quit message loop. break; } // Deal with windows message. if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; }先跳过applicationDidFinishLaunching()部分(这部分和测试用例有关系),可以看到在while主循环中做了两件事:
1. 转发窗口消息,交给之前定义的CCEGLView::_WindowProc进行处理
2. 每隔m_nAnimationInterval.QuadPart时间,也就是游戏的一帧,进行一次处理.
这里就引出了最重要的一个类CCDirector即导演类,这个类也是一个单例,负责整个游戏场景管理,逻辑更新以及绘制。那让我们看看
CCDirector::sharedDirector()->mainLoop()的每帧的mainLoop都做了啥事情:
CCDirector的帧常工作:
void CCDisplayLinkDirector::mainLoop(void) { if (m_bPurgeDirecotorInNextLoop) { m_bPurgeDirecotorInNextLoop = false; purgeDirector(); } else if (! m_bInvalid) { drawScene(); // release the objects CCPoolManager::sharedPoolManager()->pop(); } }导演类的的每帧做的最重要的事情就是drawScene,
void CCDirector::drawScene(void) { ...... if (! m_bPaused) { m_pScheduler->update(m_fDeltaTime); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw the scene if (m_pRunningScene) { m_pRunningScene->visit(); } // swap buffers if (m_pobOpenGLView) { m_pobOpenGLView->swapBuffers(); } }
读者仔细看看就会发现这个函数做了两个方面的工作,:
1. 更新调度器m_pScheduler,比如场景中的动作等,后面的博文会详细的分析
2. 绘制场景中的对象结点,树形的方式
至此,cocos2d-x的整体框架就非常清晰的摆在我们面前了,后面就开始解剖麻雀了^_^
相关文章推荐
- [置顶] spring源码剖析(一)整体 框架
- cocos2d-x整体框架源码分析以及启动过程原理(win32)
- Cocos2d-x:整体框架源码分析以及启动过程原理(win32)
- Cocos2d-x:整体框架源码分析以及启动过程原理(win32)
- cocos2d-x 源码剖析(4)
- cocos2d-x 源码剖析(7)
- cocos2d-x 源码剖析(20)
- FFmpeg源码剖析-框架:process_input()
- 【安卓网络请求开源框架Volley源码解析系列】定制自己的Request请求及Volley框架源码剖析
- STL之空间配置器源码(框架)剖析
- Mina2.0框架源码剖析(二)
- 深入集合框架之ArrayList源码剖析
- VueJs 源码分析 ---(一) 整体对 vuejs 框架的理解
- Java类集框架之HashMap(JDK1.8)源码剖析
- Caffe框架源码剖析(7)—全连接层InnerProductLayer
- 转:Mina2.0框架源码剖析(三)
- cocos2d-x 源码剖析(5)
- cocos2d-x 源码剖析(8)
- 深入集合框架之HashMap源码剖析
- cocos2d-x 源码剖析(21)