1. 程式人生 > >Cocos2d-x學習筆記(一)HelloCpp的來龍去脈

Cocos2d-x學習筆記(一)HelloCpp的來龍去脈

1】首先分析HelloCpp專案的檔案結構,分為Classes、win32、外部檔案依賴三個資料夾,其中外部依賴資料夾暫且不用理會。


Classes主要包含像導演、場景、佈景、攝像機、精靈、App相關類的申明和定義;

Win32主要是應用程式框架的WinMain函式入口(包括視窗尺寸、標題等引數的一些設定);

2】程式的來龍去脈

 WinMain函式分析:


其實此處的WinMain函式自動的引數與Windows裡面的WinMain函式非常類似,其中

 setViewName("HelloCpp")和setFrameSize(2048, 1536)用於設定應用程式標題及尺寸,setFrameZoomFactor(0.4f)用於設定幀率。那麼main函式是怎樣與導演類、場景類聯絡的呢?

這裡有一個CCApplication,很容易理解是應用程式類,類似於windows裡面的CWinApp類(記得不是很清楚,應該是這個吧),跟蹤sharedApplication()函式,此函式返回一個CCApplication*型別,再執行run()函式,這裡貼上函式程式碼:

int CCApplication::run()

{

………………………………

    // Initialize instance and cocos2d.

if (!applicationDidFinishLaunching())

{

return 0;

}

    …………………………

    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()的定義,我們可以看到這是一個虛擬函式,源程式中有這樣一段程式碼:

class  AppDelegate : private cocos2d::CCApplication

且此函式在子類中被重寫,我們可以調到函式的定義處:(附上部分程式碼)

bool AppDelegate::applicationDidFinishLaunching() {

    // initialize director

CCDirector* pDirector = CCDirector::sharedDirector();

此處的sharedDirector()函式時一個靜態成員函式,返回一個CCDirector*型別的值,這不禁讓我們聯想起單例模板,每次返回的都是同一個例項。

在函式的返回處有這樣兩句程式碼:

    CCScene *pScene = HelloWorld::scene();

    // run

    pDirector->runWithScene(pScene);

其中scene()函式很關鍵,調到此函式定義:(見註釋)

CCScene* HelloWorld::scene()

{

    // 'scene' is an autorelease object

    CCScene *scene = CCScene::create();  //建立場景物件,且自動回收記憶體

  

    // 'layer' is an autorelease object

    HelloWorld *layer = HelloWorld::create();//建立圖層(佈景層)物件,且自動回收記憶體

    // add layer as a child to scene

    scene->addChild(layer); //在場景中加入圖層

    // return the scene

    return scene;

}

這裡有一個很有意思的事情,我們透過HelloWorld類不能找到create()函式的申明,裡面巧妙的使用了巨集定義:CREATE_FUNC(HelloWorld);

#define CREATE_FUNC(__TYPE__) \

static __TYPE__* create() \

{ \

    __TYPE__ *pRet = new __TYPE__(); \

    if (pRet && pRet->init()) \

    { \

        pRet->autorelease(); \

        return pRet; \

    } \

    else \

    { \

        delete pRet; \

        pRet = NULL; \

        return NULL; \

    } \

}

由此我們可以看出其實create()函式是用巨集來替代申明的,並且其內部呼叫了init()函式用於對圖層(佈景層)進行一些初始化工作。

【3】關於init()函式

對於裡面的程式碼,學過其他庫(例如MFC)很容易看懂裡面的程式碼,主要是向圖層裡面新增選單按鈕、標籤、精靈等等,以及一些尺寸、位置的設定,這裡不再囉嗦了。

【4】心得:

剛開始研究這個引擎,看到HelloCpp這個示例程式,十分想弄清楚裡面的來龍去脈,所以在網上找了很多相關資料,整合之後作為一個筆記以後留著,有錯誤之處請大家批評指正(寫得有點亂)。