[置顶] 【玩转cocos2d-x之三】cocos2d-x游戏是怎么跑起来的

原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/12554167


虽然cocos2d-x v3.0 alpha版已经出来了,也改进了不少,有兴趣的可以去尝尝鲜。因为后面可能还会配合cocoStudio写一下博客,而现在v1.0.0.0版本需要配合cocos2d-x v2.2.0使用。所以这里选择了V2.2.0版的cocos2d-x。


一个新的东西,从头开始吧!从HelloWorld出发看一下一个cocos2d-x游戏是怎么跑起来的。先看看它的结构。

[置顶] 【玩转cocos2d-x之三】cocos2d-x游戏是怎么跑起来的_第1张图片

1.main函数

还是原来配方还是熟悉的味道。。。霸气的main函数依然是程序的入口点:

[cpp]  view plain copy
  1. //main.cpp  
  2. int APIENTRY _tWinMain(HINSTANCE hInstance,  
  3.                        HINSTANCE hPrevInstance,  
  4.                        LPTSTR    lpCmdLine,  
  5.                        int       nCmdShow)  
  6. {  
  7.     UNREFERENCED_PARAMETER(hPrevInstance);//该宏用于通知编译器不用检测变量是否使用,如果你喜欢用LV4级的警告。  
  8.     UNREFERENCED_PARAMETER(lpCmdLine);  
  9.   
  10.     // create the application instance  
  11.     AppDelegate app;//创建AppDelegate实例  
  12.     CCEGLView* eglView = CCEGLView::sharedOpenGLView();//获取CCEGLView的单一实例,因为还未创建,所以这里会进行创建  
  13.     eglView->setViewName("HelloCpp");//设置eglView属性  
  14.     eglView->setFrameSize(2048, 1536);  
  15.     eglView->setFrameZoomFactor(0.4f);  
  16.     return CCApplication::sharedApplication()->run();//调用run运行程序  
  17. }  
其中:

(1)AppDelegate继承于CCApplication,是整个游戏的程序类,如果有用过MFC的就很清楚,类似于CxxxApp。

(2)CCEGLView封装了使用openGL作为显示底层API的一个基本的Windows窗体的创建和控制。

可以简单的认为,一个控制了程序的逻辑,而另一个负责游戏的显示。


2.CCEGLView类

我们先看看上一步的CCEGLView::sharedOpenGLView()做了什么。

[cpp]  view plain copy
  1. CCEGLView* CCEGLView::sharedOpenGLView()  
  2. {  
  3.     
  4.     if (s_pEglView == NULL)//s_pEglView是一个CCEGLView指针,静态成员变量  
  5.     {  
  6.         s_pEglView = new CCEGLView();  
  7.         if(!s_pEglView->Create())//main中调用时,会执行这一步  
  8.         {  
  9.             delete s_pEglView;  
  10.             s_pEglView = NULL;  
  11.         }  
  12.     }  
  13.   
  14.     return s_pEglView;  
  15. }  

再看看,create做了什么

[cpp]  view plain copy
  1. //...  
  2. m_hWnd = CreateWindowEx(               // 创建窗体  
  3. WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,    // Extended Style For The Window  
  4. kWindowClassName,                                    // Class Name  
  5. wszBuf,                                                // Window Title  
  6. WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX,        // Defined Window Style  
  7. 0, 0,                                                // Window Position  
  8. 1000,                                               // Window Width  
  9. 1000,                                               // Window Height  
  10. NULL,                                                // No Parent Window  
  11. NULL,                                                // No Menu  
  12. hInstance,                                            // Instance  
  13. NULL );  

看到上面这一步了吧,使用Win32写过窗体的童鞋,就知道创建一个窗体需要哪些动作:

(1)填充窗口类结构WNDCLASS

(2)注册窗口

(3)创建窗口

(4)显示窗口(这一步没有在CCEGLView中实现,而是在后面的CCApplication中实现,因为这里窗口的属性还没有进行设置)

一样的,创建一个cocos2d-x的win32窗口也是要经过这些步骤。具体的就看源码吧,这里不逐句解释了。就是要注意有个WinProc函数,是用于处理主窗口消息。


3.CCApplication类

我们再看看CCApplication::sharedApplication()->run()执行的又是什么东西。

[cpp]  view plain copy
  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.     QueryPerformanceFrequency(&nFreq);//获取当前系统频率和计数  
  12.     QueryPerformanceCounter(&nLast);  
  13.   
  14.     // Initialize instance and cocos2d.  
  15.     if (!applicationDidFinishLaunching())//虚函数,调用子类的重载,这里也会设置一些显示窗口的属性  
  16.     {  
  17.         return 0;  
  18.     }  
  19.   
  20.     CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView();获取CCEGLView的单一实例  
  21.     pMainWnd->centerWindow();  
  22.     ShowWindow(pMainWnd->getHWnd(), SW_SHOW);//这里显示窗口  
  23.   
  24.     while (1)//消息循环  
  25.     {  
  26.         if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))  
  27.         {  
  28.             // 获取当前的计数  
  29.             QueryPerformanceCounter(&nNow);  
  30.   
  31.             // 判断时间流逝,是否该绘制下一帧  
  32.             if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)  
  33.             {  
  34.                 nLast.QuadPart = nNow.QuadPart;  
  35.                 CCDirector::sharedDirector()->mainLoop();//渲染场景(清除显示设备,重绘场景)  
  36.             }  
  37.             else  
  38.             {  
  39.                 Sleep(0);  
  40.             }  
  41.             continue;  
  42.         }  
  43.   
  44.         if (WM_QUIT == msg.message)//获取退出消息,跳出循环  
  45.         {  
  46.             // Quit message loop.  
  47.             break;  
  48.         }  
  49.   
  50.         // 处理Windows消息  
  51.         if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg))  
  52.         {  
  53.             TranslateMessage(&msg);  
  54.             DispatchMessage(&msg);  
  55.         }  
  56.     }  
  57.   
  58.     return (int) msg.wParam;  
  59. }  

好了,解释的应该算比较清楚了,虽然没有每一个函数都进去。。。这里再总结一下:

(1)首先先获取当前系统的频率和计数。这是一个很大的值,所以用了一个LARGE_INTEGER型变量来存储。

(2)调用子类的applicationDidFinishLaunching(),执行进入程序后的一些初始化工作。

(3)获取CCEGLView单例,显示窗口。

(4)进入循环While(1),重绘每一帧的场景。

好了,更多关于CCApplication的请看源码吧。


4.AppDelegate类

从上面的分析我们知道CCApplication::run()函数中会调用子类(AppDelegate)的applicationDidFinishLaunching函数,而这里也就是我们要设置窗口属性和运行游戏的地方了。

[cpp]  view plain copy
  1. bool AppDelegate::applicationDidFinishLaunching() {  
  2.     //第一次初始化导演,导演也是个单例类  
  3.     CCDirector* pDirector = CCDirector::sharedDirector();  
  4.   
  5.     //获得CCEGLView单例,设置窗口属性和fps等等  
  6.     CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();  
  7.   
  8.     ...  
  9.   
  10.     // 创建场景  
  11.     CCScene *pScene = HelloWorld::scene();  
  12.   
  13.     // 进入场景  
  14.     pDirector->runWithScene(pScene);  
  15.   
  16.     return true;  
  17. }  

好了,最后再总结成一张图,cocos2d-x游戏就是这么跑起来的~

[置顶] 【玩转cocos2d-x之三】cocos2d-x游戏是怎么跑起来的_第2张图片

你可能感兴趣的:(main,cocos2d-x,CCApplication,CCEGLView)