本系列博客基于cocos2dx_3.14.1版本
Application
1.继承关系
CCApplication-win32.h
class CC_DLL Application : public ApplicationProtocol
{
...
}
CCApplicationProtocol.h
class CC_DLL ApplicationProtocol
{
...
}
- ApplicationProtocol
(1) 成员函数
CCApplicationProtocol.h
virtual ~ApplicationProtocol(){
...
}
virtual bool applicationDidFinishLaunching() = 0;
virtual void applicationDidEnterBackground() = 0;
virtual void applicationWillEnterForeground() = 0;
virtual void setAnimationInterval(float interval) = 0;
virtual void initGLContextAttrs() {}
virtual LanguageType getCurrentLanguage() = 0;
virtual const char * getCurrentLanguageCode() = 0;
virtual Platform getTargetPlatform() = 0;
virtual std::string getVersion() = 0;
virtual bool openURL(const std::string &url) = 0;
该类没有成员变量,仅有成员函数,且所有成员函数均为虚函数,表明该类为接口类,子类需要自己实现相应的方法。
cocos2dx为跨平台引擎,各个平台中的平台相关实现有所差异,所以这里提供的接口类。每个平台中需要提供自己的实现。这里的分析均为基于win32平台的。
3.Application
(1)成员变量
protected:
HINSTANCE _instance;//句柄
HACCEL _accelTable;
LARGE_INTEGER _animationInterval;//帧刷新间隔时间,控制帧速率
std::string _resourceRootPath;//资源根路径
std::string _startupScriptFilename;//初始启动脚本文件
static Application * sm_pSharedApplication;//单例
这里需要特别关注的就是sm_pSharedApplication。
(2)成员函数
Application();
virtual ~Application();
int run();
static Application* getInstance();
virtual void setAnimationInterval(float interval);
virtual LanguageType getCurrentLanguage();
virtual const char * getCurrentLanguageCode();
virtual Platform getTargetPlatform();
virtual std::string getVersion() override;
virtual bool openURL(const std::string &url);
void setStartupScriptFilename(const std::string& startupScriptFile);
const std::string& getStartupScriptFilename(void)
{
return _startupScriptFilename;
}
这里需要关注的函数并不多,很多函数看名字就可以了,很多都是set、get函数。
关注的有Application(),~Application(),run(),setAnimationInterval(float interval)。
4.Application()
Application::Application()
: _instance(nullptr)
, _accelTable(nullptr)
{
//返回自身应用程序的句柄
_instance = GetModuleHandle(nullptr);
_animationInterval.QuadPart = 0;
//此时应该为 nullptr
CC_ASSERT(! sm_pSharedApplication);
// 赋值为 AppDelegate* 类型
sm_pSharedApplication = this;
}
5.~Application()
Application::~Application()
{
CC_ASSERT(this == sm_pSharedApplication);
sm_pSharedApplication = nullptr;
}
6.setAnimationInterval(float interval)
void Application::setAnimationInterval(float interval)
{
LARGE_INTEGER nFreq;
QueryPerformanceFrequency(&nFreq);//获得时钟频率 Hz/s interval 为 1/fps ,相乘即为时钟counter次数
_animationInterval.QuadPart = (LONGLONG)(interval * nFreq.QuadPart);
}
7.run()
int Application::run()
{
PVRFrameEnableControlWindow(false);
// 主消息循环:
LARGE_INTEGER nLast;
LARGE_INTEGER nNow;
QueryPerformanceCounter(&nLast);//获得当前的准确时间
initGLContextAttrs();//调用的是AppDelegate的同名函数。
// 初始化实例和cocos2d。
if (!applicationDidFinishLaunching())
{
return 1;
}
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
// Retain glview 避免在主循环被释放掉
glview->retain();
while(!glview->windowShouldClose())//一直循环
{
QueryPerformanceCounter(&nNow);
if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart)
{
nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % _animationInterval.QuadPart);
director->mainLoop();
glview->pollEvents();
}
else
{
Sleep(1);
}
}
// 如果窗口是手动关闭,那么Director还需要执行清理。
if (glview->isOpenGLReady())
{
director->end();
director->mainLoop();
director = nullptr;
}
glview->release();
return 0;
}
主要关注initGLContextAttrs(),applicationDidFinishLaunching()。
8.initGLContextAttrs()
AppDelegate.cpp
void AppDelegate::initGLContextAttrs()
{
GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
GLView::setGLContextAttrs(glContextAttrs); //设置GLView中静态变量
}
可以看一下GLContextAttrs的定义
struct GLContextAttrs
{
int redBits;
int greenBits;
int blueBits;
int alphaBits;
int depthBits;
int stencilBits;
};
应该是用于设置OpenGL属性的。
9.applicationDidFinishLaunching()
AppDelegate.cpp
bool AppDelegate::applicationDidFinishLaunching()
{
// 初始化 director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();//如果没有,需要创建(这里一定为nullptr)
if (!glview) {
glview = GLViewImpl::create("Cpp Empty Test");
director->setOpenGLView(glview);
}
director->setOpenGLView(glview);
// 设置设计分辨率
glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);
Size frameSize = glview->getFrameSize();
vector<string> searchPath;
if (frameSize.height > mediumResource.size.height)
{
searchPath.push_back(largeResource.directory);
director->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height, largeResource.size.width/designResolutionSize.width));
}
else if (frameSize.height > smallResource.size.height)
{ searchPath.push_back(mediumResource.directory);
director->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height, mediumResource.size.width/designResolutionSize.width));
}
else
{
searchPath.push_back(smallResource.directory);
director->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height, smallResource.size.width/designResolutionSize.width));
}
// set searching path
FileUtils::getInstance()->setSearchPaths(searchPath);
// turn on display FPS
director->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0f / 60);
// create a scene. it's an autorelease object
auto scene = HelloWorld::scene();
// run
director->runWithScene(scene);
return true;
}
这里首先做了一些初始化工作,如设置GLView,设计分辨率,资源根路径,是否显示FPS,设置FPS。
然后创建新场景,然后运行该场景。之后就返回了
10.继续run()
在applicationDidFinishLaunching() 之后,
while(!glview->windowShouldClose())//一直循环
{
QueryPerformanceCounter(&nNow);
if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart)
{
nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % _animationInterval.QuadPart);
director->mainLoop();
glview->pollEvents();
}
else
{
Sleep(1);
}
}
这里,程序会一直在这里循环执行,直到程序需要退出
在里面会每隔 _animationInterval 就会执行一次
director->mainLoop();
glview->pollEvents();
这里 director->mainLoop()是主要逻辑,比如定时器,绘制画面等。
总结:ApplicationProtocol是所有平台中Application需要继承的接口类。
Application是某个平台这种自定义应用的基类,内部的sm_pSharedApplication保存了自定义应用的指针。