9秒学院Cocos2d-x基础分析学习
http://www.9miaoxueyuan.com/?action=index
Cocos2d-x Win32程序流水线分析
1.首先介绍Cocos2d-x里面几个重要的单件类
CCApplication:当对象一构造后就会保存一个全局指针,通过sharedApplication静态函数获得该指针。
CCEGLView:此类不需要外部构造直接调用sharedOpenGLView静态函数即可构造该类对象并保存该指针,下次再次调用不会构造二次。
CCDirector:此类也是不需要外部构造直接调用sharedDirector静态函数即可构造,在第一次调用时会执行CCDirector的Init方法完成一些核心对象的构造包括:CCScheduler,CCActionManager,CCTouchDispatcher,CCKeypadDispatcher,CCAccelerometer,CCPoolManager。
2.win32的main.cpp代码如下
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
__int64 int64OneSecondTicks;
QueryPerformanceFrequency((LARGE_INTEGER*) &int64OneSecondTicks);
// create the application instance
AppDelegate app;
CCEGLView* eglView = CCEGLView::sharedOpenGLView();
eglView->setFrameSize(960, 640 );
return CCApplication::sharedApplication()->run();
}
下面逐步分析每句代码:
AppDelegate app;//首先构造一个应用程序(CCApplication)对象
CCEGLView* eglView = CCEGLView::sharedOpenGLView();//然后构造CCEGLView类对象
eglView->setFrameSize(960, 640 );//设置显示的分辨率,这里win32的CCEGLView类函数会创建windows下的窗口HWND,然后设置好窗口回调函数wndproc,并且初始化Opengl通过glew库来进行初始化。
return CCApplication::sharedApplication()->run();//开始跑应用程序的主循环
跳到run函数分析主循环:
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;
}
可以看出最主要的两个地方就是:
if (!applicationDidFinishLaunching())
{
return 0;
}
首先调用CCApplication的一个函数来进行初始化操作
CCDirector::sharedDirector()->mainLoop();
通过CCDirector此单件类来进行实际的主循环操作
void CCDisplayLinkDirector::mainLoop(void)
{
if (m_bPurgeDirecotorInNextLoop)
{
m_bPurgeDirecotorInNextLoop = false;
purgeDirector();
}
else if (! m_bInvalid)
{
drawScene();
// release the objects
CCPoolManager::sharedPoolManager()->pop();
}
}
可以看出最重要的函数就是我们的drawScene(),绘制当前场景。
void CCDirector::drawScene(void)
{
// 计算每帧的时间间隔(以秒为单位)
calculateDeltaTime();
//如果当前没有被暂停执行调度器的更新操作,这个调度器注入了CCActionManager对象主要是完成对它的更新
if (! m_bPaused)
{
m_pScheduler->update(m_fDeltaTime);
}
//清除BackBuffer的颜色和深度缓存
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 如果下一个场景不为NULL则将其设置为当前场景 */
if (m_pNextScene)
{
setNextScene();
}
// 压入GL矩阵,包括ModleViewMatrix,ProjectionMatrix,TextureMatrix
kmGLPushMatrix();
// 绘制当前运行场景,visit将遍历场景下面所有子节点,按照zorder排序子节点,计算出最终的显示位置并且通过opengl来绘制,按照父子的顺序依次绘制
if (m_pRunningScene)
{
m_pRunningScene->visit();
}
// 绘制NotificationNode,此节点在场景绘制之后绘制的,所以始终在最前面 ,用来做信息提示窗口那些还可以类似MessageBox
if (m_pNotificationNode)
{
m_pNotificationNode->visit();
}
//显示FPS状态信息
if (m_bDisplayStats)
{
showStats();
}
kmGLPopMatrix();
m_uTotalFrames++;
// 交换BackBuffer显示当前绘制
if (m_pobOpenGLView)
{
m_pobOpenGLView->swapBuffers();
}
if (m_bDisplayStats)
{
calculateMPF();
}
}
1.输入事件检测
1.PC上鼠标(触屏事件)
鼠标左键按下(手指按下): CCEGLViewProtocol::handleTouchesBegin
鼠标移动(手指按下滑动): CCEGLViewProtocol::handleTouchesMove
鼠标左键弹起(手指离开): CCEGLViewProtocol::handleTouchesEnd
2.keypadmessage
CCKeypadDispatcher::dispatchKeypadMSG
3.输入法输入事件
退格: CCIMEDispatcher::dispatchDeleteBackward
输入文本(UTF8字符):CCIMEDispatcher::dispatchInsertText
4.关闭应用程序
CCDirector::sharedDirector()->end();
2.精灵,精灵动画
CCSprite
1.创建一个2D的纹理对象 ------------
static CCSprite* create(const char *pszFileName);
static CCSprite* create(const char *pszFileName, const CCRect& rect);
2.对纹理对象常见操作有(平移,旋转,缩放,镜像,偏色,透明度)
setPosition(const CCPoint& pos); ------位置以纹理中心点为坐标中心
setRotation(float fRotation); ------按对象中心点以顺时针方向转动角度
void setScaleX(float fScaleX);
void setScaleY(float fScaleY);
void setFlipX(bool bFlipX);
void setFlipY(bool bFlipY);
void setColor(ccColor3B color);
void setOpacity(GLubyte b); ------透明度取值范围 [0,255]
CCActionInterval
1.平移动画
指定时间从当前位置移动到指定位置使用CCMoveTo
static CCMoveTo* create(float duration, const CCPoint& position); --- 时间(秒),到达的坐标
指定时间从当前位置在x,y轴上做偏移使用CCMoveBy
static CCMoveBy* create(float duration, const CCPoint& position); --- 时间 (秒),相对移动的位移
2.缩放动画
指定时间从当前缩放量到指定缩放量使用CCScaleTo
static CCScaleTo* create(float duration, float sx, float sy);