在不同平臺下,cocos2d-x的入口是不一樣的,在win32平臺,程序是從_tWinMain()開始的,可以在每一個cocos2d-x的程序中的main.cpp中找到。
(PS: AppDelegate繼承于CCApplication,在構造方法中,初始化CCApplication單例類的唯一實例)
代碼如下:
<span style="font-size: 14px;">int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// create the application instance
AppDelegate app;
return cocos2d::CCApplication::sharedApplication().run(); // 注意這里
}</span>
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;
}
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; }
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();}
(PS:cocos2d-x中有很多這樣的用法,即同一個頭文件,在不同平臺上實現不同)
win32平臺下的CCEGLView是一個windows窗口,具體情況CCEGLView::sharedOpenGLView();
(PS:CCEGLView還用來處理鼠標點擊模擬器觸摸,按鍵等事件的處理,如果要自定義,請參看CCEGLView::WindowProc(),這個函數是Windows程序接收消息回調)
在完成CCEGLView初始化之后,將開啟游戲渲染的主循環,即調用CCDirector::sharedDirector()->mainLoop()。這樣,程序就又交給CCDirector類來處理,CCDirector主要處理兩件事情:
<span style="font-size: 14px;">void CCDisplayLinkDirector::mainLoop(void)
{
if (m_bPurgeDirecotorInNextLoop)
{
purgeDirector();
m_bPurgeDirecotorInNextLoop = false;
}
elseif (! m_bInvalid)
{
drawScene();
// release the objects
CCPoolManager::getInstance()->pop();
}
}</span>
void CCDisplayLinkDirector::mainLoop(void){if (m_bPurgeDirecotorInNextLoop){purgeDirector(); m_bPurgeDirecotorInNextLoop = false;}else if (! m_bInvalid) { drawScene(); // release the objects CCPoolManager::getInstance()->pop(); }}
在cocos2d中渲染的根節點是CCScene(PS:CCScene也是CCNode的子類),但是在drawScene()中似乎沒有類似draw()的方法,那是因為在渲染之前,要對游戲中的節點做一些處理,包括旋轉,縮放等等,所以這個方法的名字叫visit(),而visit()是定義在CCNode中的虛方法,CCScene中并沒有單獨實現。
(PS:在每一次渲染的時候,都需要先將之前的矩陣入棧,在渲染完當前節點之后,矩陣出棧,恢復之前的矩陣)
通過CCNode::transform()對當前節點做矩陣處理(包括旋轉,縮放等等)
繪制就很簡單了,遍歷所有的子節點,采用遞歸的方式,對每一個CCNode調用visit()方法
(PS:設置Z-Order的時候可以設置為負值,有時候是很必要的,比如我們以一個人物精靈的身體為位置參照物,繪制在Z-Order為0的位置上,如果要給這個人物精靈添加一個披風耍帥,就可以將披風的Z-Order設置為負值,并且可以繼續以精靈身體作為參照物,因為cocos2d-x提供的訪問順序也是 Z-Order為負值的子節點->自身節點->Z-Order為正值的子節點)
<span style="font-size: 14px;">if(m_pChildren && m_pChildren->count() > 0)
{
// draw children zOrder < 0
ccArray *arrayData = m_pChildren->data;
for( ; i < arrayData->num; i++ )
{
pNode = (CCNode*) arrayData->arr[i];
if ( pNode && pNode->m_nZOrder < 0 )
{
pNode->visit();
}
else
{
break;
}
}
}
// self draw
this->draw();
// draw children zOrder >= 0
if (m_pChildren && m_pChildren->count() > 0)
{
ccArray *arrayData = m_pChildren->data;
for( ; i < arrayData->num; i++ )
{
pNode = (CCNode*) arrayData->arr[i];
if (pNode)
{
pNode->visit();
}
}
}</span>
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。