溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

cocos2d-x引擎結構

發布時間:2020-07-28 02:22:58 來源:網絡 閱讀:436 作者:June_Xiang 欄目:游戲開發

在不同平臺下,cocos2d-x的入口是不一樣的,在win32平臺,程序是從_tWinMain()開始的,可以在每一個cocos2d-x的程序中的main.cpp中找到。

1.程序入口

(1)在_tWinMain()中,創建的AppDelegate類的對象

PS: AppDelegate繼承于CCApplication,在構造方法中,初始化CCApplication單例類的唯一實例

(2)隨后,程序就完全交給了cocos2d-x引擎去處理

代碼如下:

 

[cpp]view plaincopyprint?
  1. <span style="font-size: 14px;">int APIENTRY _tWinMain(HINSTANCE hInstance, 

  2. HINSTANCE hPrevInstance, 

  3. LPTSTR lpCmdLine, 

  4. int nCmdShow) 

  5. UNREFERENCED_PARAMETER(hPrevInstance); 

  6. UNREFERENCED_PARAMETER(lpCmdLine); 

  7. // create the application instance

  8. AppDelegate app; 

  9. return cocos2d::CCApplication::sharedApplication().run(); // 注意這里

  10. }</span> 

     

     

    [cpp]view plaincopyprint?
    1. int CCApplication::run() 

    2. PVRFrameEnableControlWindow(false); 

    3. // Main message loop:

    4. MSG msg; 

    5. LARGE_INTEGER nFreq; 

    6. LARGE_INTEGER nLast; 

    7. LARGE_INTEGER nNow; 

    8. QueryPerformanceFrequency(&nFreq); 

    9. QueryPerformanceCounter(&nLast); 

    10. // Initialize instance and cocos2d.

    11. if (!applicationDidFinishLaunching()) 

    12. return 0; 

    13. CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView(); 

    14. pMainWnd->centerWindow(); 

    15. ShowWindow(pMainWnd->getHWnd(), SW_SHOW); 

    16. while (1)// 注意這里,主循環來了

    17. if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 

    18. // Get current time tick.

    19. QueryPerformanceCounter(&nNow); 

    20. // If it's the time to draw next frame, draw it, else sleep a while.

    21. if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart) 

    22. nLast.QuadPart = nNow.QuadPart; 

    23. CCDirector::sharedDirector()->mainLoop(); //看看這是神馬

    24. else

    25. Sleep(0); 

    26. continue

    27. if (WM_QUIT == msg.message) 

    28. // Quit message loop.

    29. break

    30. // Deal with windows message.

    31. if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg)) 

    32. TranslateMessage(&msg); 

    33. DispatchMessage(&msg); 

    34. return (int) msg.wParam; 

    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;
    }
    

    不熟悉windows的童鞋估計都知道windows是消息驅動的。這個死循環就是用來處理windows的消息循環的,在其中處理了FPS邏輯,消息分發等。注意看其中紅色標標注的
     
    [cpp]view plaincopyprint?
    1. CCDirector::sharedDirector()->mainLoop(); 

    CCDirector::sharedDirector()->mainLoop();

     

    這是神馬東西??!這個就是cocos2d-x的主循環了,由導演負責維護。從此就進入了cocos2d-x的世界,跟windows沒有一毛錢關系了。

     

int APIENTRY _tWinMain(HINSTANCE hInstance,   HINSTANCE hPrevInstance,   LPTSTR    lpCmdLine,   int       nCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);    // create the application instanceAppDelegate app;    return cocos2d::CCApplication::sharedApplication().run();}

cocos2d-x引擎結構

2.程序主循環

(1)初始化CCEGLView,在不同平臺下,CCEGLView是不同的

PS:cocos2d-x中有很多這樣的用法,即同一個頭文件,在不同平臺上實現不同

win32平臺下的CCEGLView是一個windows窗口,具體情況CCEGLView::sharedOpenGLView();

PS:CCEGLView還用來處理鼠標點擊模擬器觸摸,按鍵等事件的處理,如果要自定義,請參看CCEGLView::WindowProc(),這個函數是Windows程序接收消息回調

(2)游戲引擎的主循環

在完成CCEGLView初始化之后,將開啟游戲渲染的主循環,即調用CCDirector::sharedDirector()->mainLoop()。這樣,程序就又交給CCDirector類來處理,CCDirector主要處理兩件事情:

a. 通過引用計數實現對內存的管理

b. 游戲內元素的渲染

[cpp]view plaincopyprint?
  1. <span style="font-size: 14px;">void CCDisplayLinkDirector::mainLoop(void

  2. if (m_bPurgeDirecotorInNextLoop) 

  3. purgeDirector(); 

  4. m_bPurgeDirecotorInNextLoop = false

  5. elseif (! m_bInvalid) 

  6. drawScene(); 

  7. // release the objects

  8. CCPoolManager::getInstance()->pop(); 

  9. }</span> 

void CCDisplayLinkDirector::mainLoop(void){if (m_bPurgeDirecotorInNextLoop){purgeDirector();        m_bPurgeDirecotorInNextLoop = false;}else if (! m_bInvalid) { drawScene();  // release the objects CCPoolManager::getInstance()->pop(); }}

3.渲染

在cocos2d中渲染的根節點是CCScene(PS:CCScene也是CCNode的子類),但是在drawScene()中似乎沒有類似draw()的方法,那是因為在渲染之前,要對游戲中的節點做一些處理,包括旋轉,縮放等等,所以這個方法的名字叫visit(),而visit()是定義在CCNode中的虛方法,CCScene中并沒有單獨實現。

PS:在每一次渲染的時候,都需要先將之前的矩陣入棧,在渲染完當前節點之后,矩陣出棧,恢復之前的矩陣

(1)矩陣變化

通過CCNode::transform()對當前節點做矩陣處理(包括旋轉,縮放等等)

(2)繪制

繪制就很簡單了,遍歷所有的子節點,采用遞歸的方式,對每一個CCNode調用visit()方法

PS:設置Z-Order的時候可以設置為負值,有時候是很必要的,比如我們以一個人物精靈的身體為位置參照物,繪制在Z-Order為0的位置上,如果要給這個人物精靈添加一個披風耍帥,就可以將披風的Z-Order設置為負值,并且可以繼續以精靈身體作為參照物,因為cocos2d-x提供的訪問順序也是 Z-Order為負值的子節點->自身節點->Z-Order為正值的子節點

 

[cpp]view plaincopyprint?
  1. <span style="font-size: 14px;">if(m_pChildren && m_pChildren->count() > 0) 

  2. // draw children zOrder < 0

  3. ccArray *arrayData = m_pChildren->data; 

  4. for( ; i < arrayData->num; i++ ) 

  5. pNode = (CCNode*) arrayData->arr[i]; 

  6. if ( pNode && pNode->m_nZOrder < 0 ) 

  7. pNode->visit(); 

  8. else

  9. break

  10. // self draw

  11. this->draw(); 

  12. // draw children zOrder >= 0

  13. if (m_pChildren && m_pChildren->count() > 0) 

  14. ccArray *arrayData = m_pChildren->data; 

  15. for( ; i < arrayData->num; i++ ) 

  16. pNode = (CCNode*) arrayData->arr[i]; 

  17. if (pNode) 

  18. pNode->visit(); 

  19. }</span> 

 

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女