Cocos2d-x 3.x Helloword程序分析
此代码分析的cocos2d-x-3.13的的代码,分析win32平台下C++模式的Cocos程序。
程序入口,WinMain函数
WinMain 函数定义了一个AppDelegate类,然后调用了Run函数运行程序。
intWINAPI_tWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//create the application instance
AppDelegateapp;
returnApplication::getInstance()->run();
}
AppDelegate类
class AppDelegate : private cocos2d::Application
{
public:
AppDelegate();
virtual ~AppDelegate();
virtual voidinitGLContextAttrs();//初始化OpenGL参数
virtual bool applicationDidFinishLaunching(); //程序初始化
virtual void applicationDidEnterBackground();//程序进入后台时调用,默认实现是停止动画
virtual void applicationWillEnterForeground();//程序从后台被再次唤醒时调用,默认是启动进入后台停止的动画
};
AppDelegate是继承至Application,重写了Application的四个函数。
Application类根据不同平台进行封装的,各个平台下对外的接口基本一致,但会有一两个不一样的函数,在Win32平台下会有下面两个变量,其他平台则没有
HINSTANCE _instance; //实力句柄
HACCEL _accelTable;//快捷键句柄
Application类中有一个静态私有变量staticApplication*sm_pSharedApplication;该变量在Application类的构造函数中赋值。通过该变量实现单例模式。
Application::Application(): _instance(nullptr),_accelTable(nullptr)
{
_instance = GetModuleHandle(nullptr);
_animationInterval.QuadPart= 0;
CC_ASSERT(! sm_pSharedApplication);
sm_pSharedApplication= this;
}
Run函数
Run函数,先调用initGLContextAttrs初始化OpenGL,然后调用applicationDidFinishLaunching初始化程序,然后进入主循环。循环中每次调用Director类的MainLoop函数。
intApplication::run()
{
……
……
initGLContextAttrs();
//Initialize instance and cocos2d.
if(!applicationDidFinishLaunching())
{
return1;
}
autodirector= Director::getInstance();
autoglview= director->getOpenGLView();
//Retain glview to avoid glview being released in the while loop
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);
}
}
……
return0;
}
Application::applicationDidFinishLaunching函数
boolAppDelegate::applicationDidFinishLaunching()
{
//initialize director
autodirector= Director::getInstance();
autoglview= director->getOpenGLView();
if(!glview){//1. 创建OpenGL窗口
#if (CC_TARGET_PLATFORM== CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)|| (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
glview= GLViewImpl::createWithRect("Hello", cocos2d::Rect(0,0, designResolutionSize.width,designResolutionSize.height));
#else
glview= GLViewImpl::create("Hello");
#endif
director->setOpenGLView(glview);
}
//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);
//Set the design resolution
glview->setDesignResolutionSize(designResolutionSize.width,designResolutionSize.height,ResolutionPolicy::NO_BORDER);
autoframeSize= glview->getFrameSize();
//if the frame's height is larger than the height of medium size.
if(frameSize.height> mediumResolutionSize.height)
{
director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height,largeResolutionSize.width/designResolutionSize.width));
}
//if the frame's height is larger than the height of small size.
elseif(frameSize.height> smallResolutionSize.height)
{
director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height,mediumResolutionSize.width/designResolutionSize.width));
}
//if the frame's height is smaller than the height of medium size.
else
{
director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height,smallResolutionSize.width/designResolutionSize.width));
}
register_all_packages();
//create a scene. it's an autorelease object
autoscene= HelloWorld::createScene();
//run
director->runWithScene(scene);
returntrue;
}
AppDelegate::applicationDidFinishLaunching是重写Appliction类的函数。
该函数实现了以下功能:
1. 创建OpenGL窗口
2. 设置是否显示FPS等状态信息,左下角的帧率信息(setDisplayStats)
3. 设置帧率默认最大60帧每秒(setAnimationInterval(1.0f / 60);)
4. 设置游戏窗口大小,分辨率。
5. 注册脚本函数,Javascript或Lua函数的脚本(register_all_packages();)
6. 创建场景并运行场景
mainLoop函数
voidDisplayLinkDirector::mainLoop()
{
if(_purgeDirectorInNextLoop)//程序是否关闭,调用Director::end函数会设为ture
{
_purgeDirectorInNextLoop= false;
purgeDirector();//关闭程序
}
elseif(_restartDirectorInNextLoop)
{
_restartDirectorInNextLoop= false;
restartDirector();
}
elseif(! _invalid)
{
drawScene();//内部实现了绘制场景,响应事件,运行动画
//release the objects
PoolManager::getInstance()->getCurrentPool()->clear();//清理内存池
}
}
mainLoop是一个If.else的结构,首先检查是否要结束程序,然后检查是否要重置程序,最后是绘制场景和清理内存池。