上一篇文章中有一个在栈中创建的实例——AppDelegate。这个类的初始化使cocos2d-x的程序能够执行起来。由于它是继承于CCApplication类。而执行的run方法就是在此类中实现的。

class CC_DLL CCApplication : public CCApplicationProtocol
{
public:
CCApplication();
virtual ~CCApplication(); /**
@brief Run the message loop.
*/
virtual int run(); /**
@brief Get current applicaiton instance.
@return Current application instance pointer.
*/
static CCApplication* sharedApplication(); /* override functions */
virtual void setAnimationInterval(double interval);
virtual ccLanguageType getCurrentLanguage(); /**
@brief Get target platform
*/
virtual TargetPlatform getTargetPlatform(); /**
* Sets the Resource root path.
* @deprecated Please use CCFileUtils::sharedFileUtils()->setSearchPaths() instead.
*/
CC_DEPRECATED_ATTRIBUTE void setResourceRootPath(const std::string& rootResDir); /**
* Gets the Resource root path.
* @deprecated Please use CCFileUtils::sharedFileUtils()->getSearchPaths() instead.
*/
CC_DEPRECATED_ATTRIBUTE const std::string& getResourceRootPath(void); void setStartupScriptFilename(const std::string& startupScriptFile); const std::string& getStartupScriptFilename(void)
{
return m_startupScriptFilename;
} protected:
HINSTANCE m_hInstance;
HACCEL m_hAccelTable;
LARGE_INTEGER m_nAnimationInterval;
std::string m_resourceRootPath;
std::string m_startupScriptFilename; static CCApplication * sm_pSharedApplication;
}; NS_CC_END #endif // __CC_APPLICATION_WIN32_H__

能够看到,CCApplication是继承自于CCApplicationProtocol,CCApplicationProtocol是个纯虚类。生命了程序启动,切到后台,后台唤醒等函数。

class CC_DLL CCApplicationProtocol
{
public: virtual ~CCApplicationProtocol() {} /**
@brief Implement CCDirector and CCScene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
//游戏第一次执行时被调用,用于初始场景和载入场景
virtual bool applicationDidFinishLaunching() = 0; /**
@brief The function be called when the application enter background
@param the pointer of the application
*/
//当游戏进入后台时被调用。 virtual void applicationDidEnterBackground() = 0; /**
@brief The function be called when the application enter foreground
@param the pointer of the application
*/
//从后台被唤醒时调用。
virtual void applicationWillEnterForeground() = 0; /**
@brief Callback by CCDirector for limit FPS.
@interval The time, expressed in seconds, between current frame and next.
*/
//设置帧数
virtual void setAnimationInterval(double interval) = 0; /**
@brief Get current language config
@return Current language config
*/
//获取语言
virtual ccLanguageType getCurrentLanguage() = 0; /**
@brief Get target platform
*/
//获取执行的平台
virtual TargetPlatform getTargetPlatform() = 0;
};

而CCApplication仅仅实现了setAnimationInterval,getCurrentLanguage和getTargetPlatform三个函数,另外三个交给CCApplication的子类,也就是AppDelegate来实现。例如以下代码所看到的:

class  AppDelegate : private cocos2d::CCApplication
{
public:
AppDelegate();
virtual ~AppDelegate(); /**
@brief Implement CCDirector and CCScene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching(); /**
@brief The function be called when the application enter background
@param the pointer of the application
*/
virtual void applicationDidEnterBackground(); /**
@brief The function be called when the application enter foreground
@param the pointer of the application
*/
virtual void applicationWillEnterForeground();
};

bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
CCDirector* pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); pDirector->setOpenGLView(pEGLView); // 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;
} // This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {
CCDirector::sharedDirector()->stopAnimation(); // if you use SimpleAudioEngine, it must be pause
// SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
} // this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
CCDirector::sharedDirector()->startAnimation(); // if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

事实上现非常easy。

在applicationDidFinishLaunching函数中先初始化导演。设置是否显示FPS,设置帧率,创建场景。载入和执行场景。applicationDidEnterBackground则让导演停止渲染,applicationWillEnterForeground则让导演继续渲染。

上面说到applicationDidFinishLaunching在程序一启动就会被调用,而在main函数中仅仅是创建了一个AppDelegate的实例。而AppDelegate的实例并没有主动调用该方法,那么它的调用肯定是在它的父类在调用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;
}

这个函数的主要逻辑是先调用子类的applicationDidFinishLaunching函数,运行创建场景等操作,然后设置窗体,最后将整个拥有权交给导演类的主循环,也就是死循环中的mainLoop函数的调用,当然在调用前还要推断当前的帧率与上一帧的帧率之差是否大于设置的帧率。否则不调用。

总结:从上面的过程能够看出CCApplication类是整个程序的起始控制类,里面运行了让游戏真正跑起来的主循环,其次还定义了整个程序的运行环境。像设置帧率。获取当前的运行平台等。另外,因为CCApplication是个单例共享类,能够在程序中随时获取当前的平台信息,设置/获取资源的根路径等操作。

cocos2d-x入口类的更多相关文章

  1. Spring Boot 2.x 启动全过程源码分析(上)入口类剖析

    Spring Boot 的应用教程我们已经分享过很多了,今天来通过源码来分析下它的启动过程,探究下 Spring Boot 为什么这么简便的奥秘. 本篇基于 Spring Boot 2.0.3 版本进 ...

  2. Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析

    前言 前些天,测试MM发现了一个比较奇怪的bug. 具体表现是: 1.将app包通过电脑QQ传送到手机QQ上面,点击安装,安装后选择打开app (此间的应用逻辑应该是要触发 [闪屏页Activity] ...

  3. SpringBoot主程序类,主入口类

    主程序类,主入口类 /** * @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用 */ @SpringBootApplication publi ...

  4. 【转载】Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析

    前言 前些天,测试MM发现了一个比较奇怪的bug. 具体表现是: 1.将app包通过电脑QQ传送到手机QQ上面,点击安装,安装后选择打开app (此间的应用逻辑应该是要触发 [闪屏页Activity] ...

  5. SpringBoot入门(三)——入口类解析

    本文来自网易云社区 上一篇介绍了起步依赖,这篇我们先来看下SpringBoot项目是如何启动的. 入口类 再次观察工程的Maven配置文件,可以看到工程的默认打包方式是jar格式的. <pack ...

  6. 入口类和@SpringBootApplication

    SpringBoot通常有一个名为*Application的入口类,入口类里有一个标准的Java应用的入口方法,main方法,在该方法中使用SpringApplication.run(xxxxxApp ...

  7. Cocos2d-x 3.0final 终结者系列教程05-AppDelegate入口类

    下面是Cocos2d-x的程序入口: class  AppDelegate : private cocos2d::Application { public: AppDelegate(); virtua ...

  8. cocos2d中个类之间的关系

    1.Director类: (1)单例类Director::getInstance()  ,获取导演类对象 (2)设置游戏配置(OpenGL),推动游戏发展 runWithSence.replaceSe ...

  9. 尚硅谷springboot学习5-主入口类说明

    package com.atguigu; import org.springframework.boot.SpringApplication; import org.springframework.b ...

随机推荐

  1. LaTeX新人教程,30分钟从完全陌生到基本入门[转载]

    LaTeX新人教程,30分钟从完全陌生到基本入门[转载] 2017-02-05 分类:TeX讲义 阅读(32514) 评论(0)  这是一篇老文了,前几天看微博的时候看到的,文中的很多表达比较过激,思 ...

  2. hnust 不爱学习的小w

    问题 C: 不爱学习的小W 时间限制: 2 Sec  内存限制: 64 MB提交: 1431  解决: 102[提交][状态][讨论版] 题目描述 “叮铃铃”上课了,同学们都及时到了教室坐到了座位上, ...

  3. [持续集成学习篇]【1】[jenkins安装与配置]

    Guided Tour This guided tour will use the "standalone" Jenkins distribution which requires ...

  4. struts转换器详解

    struts转换器:在B/S应用中,将字符串请求参数转换为相应的数据类型,是MVC框架提供的功能,而Struts2是很好的MVC框架实现者,理所当然,提供了类型转换机制. 一.类型转换的意义 对于一个 ...

  5. 【Luogu】P3705新生舞会(费用流+分数规划+二分答案)

    题目链接 本来以为自己可以做出来,结果……打脸了 (貌似来wc立了好几个flag了,都没竖起来) 不过乱蒙能蒙出一个叫“分数规划”的东西的式子还是很开心的 观察$C=\frac{a_{1}+a_{2} ...

  6. ACM程序设计选修课——1076汇编语言(重定向+模拟)

    1076: 汇编语言 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 34  Solved: 4 [Submit][Status][Web Board] ...

  7. 洛谷P4363 [九省联考2018]一双木棋chess 【状压dp】

    题目 菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束. 落子的规则是:一个格子可以落子当且仅当这个 ...

  8. python算法与数据结构-顺序表(37)

    1.顺序表介绍 顺序表是最简单的一种线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以快速定位第几个元素,中间不允许有空,所以插入.删除时需要移动大量元素.顺序表可以分配一段连续的存储空间 ...

  9. 关于记忆力:遵从一些原则,自省增加经验,there is a way out of almost everything

    年轻人记忆力减退的原因不同于老年人,由疾病所引起的占极少数,一般都是由于学习生活等因素造成精神高度紧张或连续用脑过度使神经疲劳所致. 学会科学的分析和考虑问题的方法,对提高记忆力来说是最为首要的. 保 ...

  10. poj 1410 Intersection 线段相交

    题目链接 题意 判断线段和矩形是否有交点(矩形的范围是四条边及内部). 思路 判断线段和矩形的四条边有无交点 && 线段是否在矩形内. 注意第二个条件. Code #include & ...