最刚开始分平台调用原生的提示,但是由于项目之后要显示的内容变的复杂,只好研究一下全局的游戏公告该怎么显示了。
直接addChild的是行不通的,或者处理起来比较繁琐,因为每次切换scene都会清空。
研究了一下cocos2dx的渲染机制。
入口:
CCApplication::sharedApplication()->run()
CCDirecor会周期执行一个mainLoop
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;
}
mainLoop里面又会draw当前的scene:
void CCDisplayLinkDirector::mainLoop(void)
{
if (m_bPurgeDirecotorInNextLoop)
{
m_bPurgeDirecotorInNextLoop = false;
purgeDirector();
}
else if (! m_bInvalid)
{
drawScene();
// release the objects
CCPoolManager::sharedPoolManager()->pop();
}
}
重点是在drawScene里面有一个m_pNotificationNode:
// Draw the Scene
void CCDirector::drawScene(void)
{
// calculate "global" dt
calculateDeltaTime();
//tick before glClear: issue #533
if (! m_bPaused)
{
m_pScheduler->update(m_fDeltaTime);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* to avoid flickr, nextScene MUST be here: after tick and before draw.
XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */
if (m_pNextScene)
{
setNextScene();
}
kmGLPushMatrix();
// draw the scene
if (m_pRunningScene)
{
m_pRunningScene->visit();
}
// draw the notifications node
if (m_pNotificationNode)
{
m_pNotificationNode->visit();
}
if (m_bDisplayStats)
{
showStats();
}
kmGLPopMatrix();
m_uTotalFrames++;
// swap buffers
if (m_pobOpenGLView)
{
m_pobOpenGLView->swapBuffers();
}
if (m_bDisplayStats)
{
calculateMPF();
}
}
查看m_pNotificationNode定义
/* This object will be visited after the scene. Useful to hook a notification node */
CCNode *m_pNotificationNode;
所以创建一个游戏公告层:
NoticeBoard* noticeBoard = NoticeBoard::create();
pDirector->setNotificationNode(noticeBoard);
这样两行代码就可以实现全局的游戏公告,不受切换场景的影响了。