• cocos2d-x游戏是怎么跑起来的


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

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

    1.main函数

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

    [cpp] view plaincopy
     
     
    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 plaincopy
     
     
    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 plaincopy
     
     
    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 plaincopy
     
     
    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 plaincopy
     
     
    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游戏就是这么跑起来的~

  • 相关阅读:
    VueJS中学习使用Vuex详解
    https://www.cnblogs.com/chinabin1993/p/9848720.html
    5分钟带你入门vuex(vue状态管理)
    引用第三方 chalk 模块
    Vue-Grid-Layout分享一款好用的可拖拽组件
    vue-grid-layout
    拖拽 ‘vue-grid-layout’ 插件了解下
    Vue国际化处理 vue-i18n 以及项目自动切换中英文
    Java线程池ThreadPoolExecutor使用和分析(三)
    Java线程池ThreadPoolExecutor使用和分析(二)
  • 原文地址:https://www.cnblogs.com/zhepama/p/3795713.html
Copyright © 2020-2023  润新知