In the previous article, there was an instance created in the stack -- AppDelegate, whose class initialization allowed the cocos2d-x program to run. Because it inherits from the CCApplication class, the run method is implemented in this class.
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__As you can see, CCApplication is inherited from CCApplicationProtocol, and CCApplicationProtocol is a pure virtual class. It contains functions such as starting a program, switching to the background, and waking up the background.
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. * /// called during the first game running, used for initial and loading scenarios. virtual bool applicationDidFinishLaunching () = 0; /** @ brief The function be called when the application enter background @ param the pointer of the application * // called when The game enters the background. Virtual void applicationDidEnterBackground () = 0;/** @ brief The function be called when the application enter foreground @ param the pointer of the application * // called when The application is awakened from the background. Virtual void applicationWillEnterForeground () = 0;/** @ brief Callback by CCDirector ctor for limit FPS. @ interval The time, expressed in seconds, between current frame and next. * /// set the number of frames. virtual void setAnimationInterval (double interval) = 0; /** @ brief Get current language config @ return Current language config * // obtain the language virtual ccLanguageType getCurrentLanguage () = 0; /** @ brief Get target platform * // obtain the running platform virtual TargetPlatform getTargetPlatform () = 0 ;};
The CCApplication only implements the setAnimationInterval, getCurrentLanguage, and getTargetPlatform functions. The other three are assigned to the CCApplication subclass, that is, AppDelegate. The following code is used:
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 toovoid 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 againvoid AppDelegate::applicationWillEnterForeground() { CCDirector::sharedDirector()->startAnimation(); // if you use SimpleAudioEngine, it must resume here // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();}Its implementation is simple. Initialize the director in the applicationDidFinishLaunching function, set whether to display FPS, set frame rate, create scenario, load and run scenario. ApplicationDidEnterBackground enables the Director to stop rendering, and applicationWillEnterForeground allows the Director to continue rendering.
As mentioned above, applicationDidFinishLaunching will be called once the program is started. In the main function, only an AppDelegate instance is created, and the AppDelegate instance does not actively call this method, therefore, it must be called when its parent class calls the run function.
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;}The main logic of this function is to first call the sub-class applicationDidFinishLaunching function, execute operations such as scenario creation, then set the window, and finally give the entire ownership to the main loop of the director class, that is, the mainLoop function in the endless loop is called. before calling the function, you must determine whether the difference between the current frame rate and the previous frame rate is greater than the set frame rate. Otherwise, the function is not called.
Summary: From the process above, we can see that the CCApplication class is the starting control class of the entire program, which executes the main loop that truly enables the game to run, and secondly defines the execution environment of the entire program. Such as setting Frame Rate and obtaining the current running platform. In addition, because CCApplication is a singleton sharing class, you can obtain the current platform information at any time in the program and set/obtain the root path of the resource.