上一篇文章中有一个在栈中创建的实例——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. AtCoder Grand Contest 020

    A - Move and Win Time limit : 1sec / Memory limit : 512MB Score : 300 points Problem Statement A gam ...

  2. [错误处理]UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)

    Stackoverflow 回答: 将byte类型转化:byte_string.decode('utf-8') Jinja2 is using Unicode internally which mea ...

  3. Spring 依赖注入(一、注入方式)

    首先装配一个实体类People package com.maya.model; public class People { private int id; private String name; p ...

  4. 算法复习——状压dp

    状压dp的核心在于,当我们不能通过表现单一的对象的状态来达到dp的最优子结构和无后效性原则时,我们可能保存多个元素的有关信息··这时候利用2进制的01来表示每个元素相关状态并将其压缩成2进制数就可以达 ...

  5. [USACO11DEC] Grass Planting (树链剖分)

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  6. nginx 变量 + lua

    nginx变量使用方法详解(8) nil.null与ngx.null 发现一个nginx LUA开发Web App的框架 nginx是个好东西, nginx的openrtsy发行版本更是个好东西. 今 ...

  7. poj 3068 Bridge Across Islands

    Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11196   Accepted: ...

  8. [LeetCode] Text Justification words显示的排序控制

    Given an array of words and a length L, format the text such that each line has exactly L characters ...

  9. mybatis动态sql片段与分页,排序,传参的使用与一对多映射与resultMap使用

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-/ ...

  10. 转 markdown编写规则、语法

    http://www.jianshu.com/p/1e402922ee32/ Markdown——入门指南 字数2231 阅读307754 评论115 喜欢1350 转载请注明原作者,如果你觉得这篇文 ...