Cocos2d-lua下的Mac/ios啟動流程
文章目錄
- Cocos2d-lua下的Mac/ios啟動流程
- 前言
- 一、新建cocos2d-lua工程
- 二、使用xcode打開/MyGameLuaTest.xcodeproj工程
- 1.ios下的AppController.mm的原始碼:
- 2.接下來看看AppDelegate.h的原始碼:
- 2.接下來看看CCApplication.h的原始碼:
- 4.以CCApplication-ios.h/CCApplication-ios.mm的原始碼為例:
- 總結
前言
深入原始碼,學習Application,ApplicationProtocol,AppDelegate三個類的作用,以及相互之間的關系,并且了解cocos2d-lua下mac/ios的啟動流程,
ios/mac下的AppController—>AppDelegate—>cocos2d::Application(ios/mac)::run()
,
提示:以下是本篇文章正文內容,下面案例可供參考
一、新建cocos2d-lua工程
使用命令新建工程
cocos new -l lua -p com.game.myluatest -d ./ MyGameLuaTest
二、使用xcode打開/MyGameLuaTest.xcodeproj工程
使用xcode打開MyGameLuaTest/frameworks/runtime-src/proj.ios_mac/MyGameLuaTest.xcodeproj工程,左邊欄目專案代碼中MyGameLuaTest下ios/mac就是對應平臺下的啟動原始碼:
1.ios下的AppController.mm的原始碼:
// cocos2d application instance
static AppDelegate s_sharedApplication;
創建了一個靜態全域AppDegate物件,直到程式結束,自動銷毀,
2.接下來看看AppDelegate.h的原始碼:
class AppDelegate : private cocos2d::Application
{
public:
AppDelegate();
virtual ~AppDelegate();
virtual void initGLContextAttrs();
/**
@brief Implement Director and Scene 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();
};
由此可見AppDelegate繼承了Application,有4個方法是由AppDelegate類中實作,這4個方法來自于ApplicationProtocol,
以下是ApplicationProtocol.h原始碼:
/** Subclass override the function to set OpenGL context attribution instead of use default value.
* And now can only set six attributions:redBits,greenBits,blueBits,alphaBits,depthBits,stencilBits.
* Default value are(5,6,5,0,16,0), usually use as follows:
* void AppDelegate::initGLContextAttrs(){
* GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
* GLView::setGLContextAttrs(glContextAttrs);
* }
*/
virtual void initGLContextAttrs() {}
/**
* @brief Implement Director and Scene init code here.
* @return true Initialize success, app continue.
* @return false Initialize failed, app terminate.
* @js NA
* @lua NA
*/
virtual bool applicationDidFinishLaunching() = 0;
/**
* @brief This function will be called when the application enters background.
* @js NA
* @lua NA
*/
virtual void applicationDidEnterBackground() = 0;
/**
* @brief This function will be called when the application enters foreground.
* @js NA
* @lua NA
*/
virtual void applicationWillEnterForeground() = 0;
然而 cocos2d::Application 又繼承了 ApplicationProtocol,并且AppDelegate中只有4個方法:
1.initGLContextAttrs:初始化glContext;
2.applicationDidFinishLaunching:app加載完成,在此方法實作Director以及Scene的初始化;
3.applicationDidEnterBackground:app進入后臺時候的回呼方法;
4.applicationWillEnterForeground:app進入到前臺的時候的回呼方法;
cocos2dx通過設定app代理的方式,在只修改AppDelegate中的代碼來實作跨平臺功能;即如果需要在回到后臺時候,實作一些功能,比如清理一些不常用的文理快取,只需要在applicationDidEnterBackground的方法中實作,即可實作跨平臺的效果,即各個平臺(ios/mac/android/win32/winrt/linux)同時適用,為什么,接下來繼續看下面代碼,
2.接下來看看CCApplication.h的原始碼:
#if CC_TARGET_PLATFORM == CC_PLATFORM_MAC
#include "platform/mac/CCApplication-mac.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS
#include "platform/ios/CCApplication-ios.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "platform/android/CCApplication-android.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#include "platform/win32/CCApplication-win32.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
#include "platform/winrt/CCApplication.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_LINUX
#include "platform/linux/CCApplication-linux.h"
#endif
在頭檔案原始碼中,在不同平臺下引入不同的CCApplication的頭檔案
4.以CCApplication-ios.h/CCApplication-ios.mm的原始碼為例:
以下是CCApplication-ios.h原始碼:繼承了ApplicationProtocol
//在CCApplication-ios.h檔案中
class CC_DLL Application : public ApplicationProtocol
...省略若干
/**
@brief Run the message loop.
*/
int run();
/**
@brief Get the current application instance.
@return Current application instance pointer.
*/
static Application* getInstance();
protected:
static Application * sm_pSharedApplication;
以下是CCApplication-ios.mm原始碼:
Application* Application::sm_pSharedApplication = 0;
Application::Application()
{
CC_ASSERT(! sm_pSharedApplication);
sm_pSharedApplication = this;
}
/
// static member function
//
Application* Application::getInstance()
{
CC_ASSERT(sm_pSharedApplication);
return sm_pSharedApplication;
}
回到第一點中的AppController.mm的原始碼,初始化全域靜態的AppDelegate的物件;其實默認呼叫了父類的CCApplication無引數建構式,即次例CCApplication-ios.mm中的靜態成員變數sm_pSharedApplication是本身CCApplication物件實體的一個指標,因此cocos2d::Application *app = cocos2d::Application::getInstance()回傳的是各個平臺下CCApplication物件的實體,
AppController.mm原始碼:
// cocos2d application instance
static AppDelegate s_sharedApplication;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
cocos2d::Application *app = cocos2d::Application::getInstance();
...省略若干行代碼
//run the cocos2d-x game scene
app->run();
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
*/
cocos2d::Application::getInstance()->applicationDidEnterBackground();
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
/*
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
*/
cocos2d::Application::getInstance()->applicationWillEnterForeground();
}
1.當AppController.mm中呼叫app->run();方法時候,就是呼叫了CCApplication其父類ApplicationProtocol中的applicationDidFinishLaunching方法,但是唯一實作就是AppDelegate檔案中,
2.當ios的AppController.mm進入applicationDidEnterBackground方法時候(應用轉到后臺)會呼叫cocos2d::Application::getInstance()->applicationDidEnterBackground();
3.當iosAppController進入applicationWillEnterForegroundy應用將要前臺)的時候呼叫cocos2d::Application::getInstance()->applicationWillEnterForeground();
CCApplication-ios.mm原始碼:
int Application::run()
{
if (applicationDidFinishLaunching())
{
[[CCDirectorCaller sharedDirectorCaller] startMainLoop];
}
return 0;
}
然后呼叫[[CCDirectorCaller sharedDirectorCaller] startMainLoop];
即CCDirectorCaller中的startMainLoop開啟ios中螢屏重繪的定時器,CADisplayLink是一個能讓我們以和螢屏重繪率相同的頻率將內容畫到螢屏上的定時器,原始碼中創建一個新的 CADisplayLink 物件,把它添加到一個runloop中,并給它提供一個 target 和selector 在螢屏重繪的時候呼叫,在每次重繪螢屏的時候呼叫
cocos2d::Director* director = cocos2d::Director::getInstance();
director->mainLoop(dt)
CCDirectorCaller.mm原始碼:
-(void) startMainLoop
{
// Director::setAnimationInterval() is called, we should invalidate it first
[self stopMainLoop];
displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];
[displayLink setFrameInterval: self.interval];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
-(void) doCaller: (id) sender
{
if (isAppActive) {
cocos2d::Director* director = cocos2d::Director::getInstance();
EAGLContext* cocos2dxContext = [(CCEAGLView*)director->getOpenGLView()->getEAGLView() context];
if (cocos2dxContext != [EAGLContext currentContext])
glFlush();
[EAGLContext setCurrentContext: cocos2dxContext];
CFTimeInterval dt = ((CADisplayLink*)displayLink).timestamp - lastDisplayTime;
lastDisplayTime = ((CADisplayLink*)displayLink).timestamp;
director->mainLoop(dt);
}
}
此時正式進入Cocos2dx主回圈當中,
CCDirector.cpp原始碼:
void Director::mainLoop(float dt)
{
_deltaTime = dt;
_deltaTimePassedByCaller = true;
mainLoop();
}
void Director::mainLoop()
{
if (_purgeDirectorInNextLoop)
{
_purgeDirectorInNextLoop = false;
purgeDirector();
}
else if (_restartDirectorInNextLoop)
{
_restartDirectorInNextLoop = false;
restartDirector();
}
else if (! _invalid)
{
drawScene();
// release the objects
PoolManager::getInstance()->getCurrentPool()->clear();
}
}
2.mac下的Info.plist
總結
以ios啟動流程為例,在檔案AppController.mm中,創建AppDelegate物件,AppDelegate繼承CCApplication,而CCApplication則繼承ApplicationProtocol;然后AppController.mm中呼叫了CCApplication的run方法,而run方法中呼叫了ApplicationProtocol的applicationDidFinishLaunching方法(實作方法在AppDelegate中),還有開啟了ios中螢屏重繪的定時器CADisplayLink,每次螢屏重繪呼叫doCaller方法,此方法中執行了CCDirector中的mainLoop(dt)方法,從而進入了Cocos2dx的主回圈當中,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/113782.html
標籤:其他
上一篇:在spyder上做貝葉斯分析,瘋狂報錯。大佬們,看不懂這個錯誤碼啥意思啊
下一篇:matlab 一副影像的對比度值
