-- 启动--
启动应用程序后,在main函数中执行
UIApplicationMain(argc, argv,nil, @"AppController");
进入UIApplicationMain中查看,根据文档说明,UIApplicationMain中最后两个参数是初始化应用程序,函数原型为:
UIKIT_EXTERNint UIApplicationMain(int argc,char *argv[], NSString *principalClassName,NSString *delegateClassName);
当principalClassName为空时,程序会去Info.plist文件去寻找键为“NSPrincipalClass”的类名,如果没有,则使用delegateClassName来进行初始化。--AppController的执行--
根据参数@"AppController"初始化AppController类,这个类实现UIApplicationDelegate的代理方法didFinishLaunchingWithOptions
在该方法中,初始化UIWindow以及OpenGL的相关初始化,这个方法最后执行
cocos2d::CCApplication::sharedApplication()->run();
--进入run()方法--
cocos2d::CCApplication::sharedApplication()->run();
中run方法为:
intCCApplication::run()
{
if (applicationDidFinishLaunching())
{
[[CCDirectorCallersharedDirectorCaller] startMainLoop];
}
return 0;
}
这个中间的applicationDidFinishLaunching()方法是怎么回事呢?--applicationDidFinishLaunching()方法的执行--
CCApplicationProtocol有一个applicationDidFinishLaunching()方法,那么这个方法是如何实作的呢?,我们继续往下看,CCApplicationProtocol中方法定义如下:
virtualbool applicationDidFinishLaunching() = 0;
这个方法是一个虚的方法,那么它的实作只有在它的子类中实现的,鼠标点击applicationDidFinishLaunching()+按下command显示
class AppDelegate :private cocos2d::CCApplication, AppDelegate是cocos2d::CCApplication的子类,那么就是说AppDelegate是CCApplicationProtocol的孙子辈,爷爷的基因最终在孙子的身上显现出来。
事情还没有完,我们看看在AppDelegate里的applicationDidFinishLuanching()中都做了哪些工作,
boolAppDelegate::applicationDidFinishLaunching()
{
// initialize director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
// enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
// pDirector->enableRetinaDisplay(true);
// turn on display FPS
pDirector->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 /60);
// create a scene. it's an autorelease object
CCScene *pScene = HelloWorld::scene();
// run
pDirector->runWithScene(pScene);
return true;
}
很明白了,设置导演,加载OpenGL,设置显示状态,刷屏频率最后加载场景。
--回到run中看[[CCDirectorCaller sharedDirectorCaller] startMainLoop]--
我们刚看到在AppDelegate里面的applicationDidFinishLaunching()中设置了导演,加载OpenGL等,下面我们看看 startMainLoop:
-(void) startMainLoop
{
// CCDirector::setAnimationInterval() is called, we should invalidate it first
[displayLinkinvalidate];
displayLink = nil;
displayLink = [NSClassFromString(@"CADisplayLink")displayLinkWithTarget:selfselector:@selector(doCaller:)];
[displayLinksetFrameInterval:self.interval];
[displayLinkaddToRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];
}
这个里面做的最重要的两件事情是获取显示链(这个显示链是隶属于导演的)并添加到循环中。下面我们看看获取显示链的时候的doCaller方法。--doCaller--
-(void) doCaller: (id) sender
{
cocos2d::CCDirector::sharedDirector()->mainLoop();
}
doCaller中调用导演执行mainLoop()方法。
voidCCDisplayLinkDirector::mainLoop(void)
{
if (m_bPurgeDirecotorInNextLoop)
{
m_bPurgeDirecotorInNextLoop = false;
purgeDirector();
}
else if (! m_bInvalid)
{
drawScene();
// release the objects
CCPoolManager::sharedPoolManager()->pop();
}
}
也很简单,就是绘制场景和弹栈,比较重要的也就是drawScene()这个方法。
这里我把方法贴一下,就不再多描述了
// Draw the Scene
voidCCDirector::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();
}
}