天天看點

COCOS學習筆記--Cocos項目工程是怎樣運作起來的?

好多使用Cocos引擎的開發者有沒有考慮過這樣一個問題,我們建立好的Cocos項目是怎樣運作起來的呢?其工程入口又在哪裡呢?

那麼我們先來看看我們工程目錄的結構:

COCOS學習筆記--Cocos項目工程是怎樣運作起來的?

釋出工程後我們會看到工程檔案目錄下有Classes子目錄,Classes是用來存放使用者自己寫的C++檔案,其中還包含了建立工程時生成的類AppDelegate.h、AppDelegate.cpp和HelloWorldScene.h、HelloWorldScene.cpp。Classes目錄下的源檔案是所有6個平台共用的代碼檔案,不管是android還是ios都使用這個目錄下的源檔案,屬于真正跨平台部分的代碼;

win32目錄下的源檔案有一個main主入口檔案,負責win32平台下對遊戲的調用。其實在對應的proj.android的工程裡也有一個android平台對應的main主入口檔案,隻是由于平台的不同實作代碼也各有不同,但是目的一樣;

另外工程目錄下還有個Resources子目錄,用于存放資源檔案,其目錄下res檔案中有一個MainScene.csb檔案,這是我們釋出項目時生成的二進制檔案,它主要用來儲存CocoStudio編輯的場景檔案,通過該檔案來顯示我們編輯好的場景。

項目運作主要看Classes目錄下的AppDelegate、HelloWorldScene兩個類。

我們先看AppDelegate.cpp類:

class  AppDelegate : private cocos2d::Application
{
public:
    AppDelegate();
    virtual ~AppDelegate();
 
    virtual void initGLContextAttrs();
    virtual bool applicationDidFinishLaunching();
    virtual void applicationDidEnterBackground();
    virtual void applicationWillEnterForeground();
};
           

AppDelegate類中除構造、析構函數外主要有四個方法:

//設定 OpenGL context 屬性,該設定對所有平台都有效
void AppDelegate::initGLContextAttrs()
{
    //設定6個屬性:red,green,blue,alpha,depth,stencil
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
    GLView::setGLContextAttrs(glContextAttrs);
}
           
//當應用程式啟動時執行,遊戲程式啟動入口
//在這裡我們啟動了第一個scene(場景)
//在具體遊戲中通常在這裡啟動loading界面
//你的遊戲從這裡開始
bool AppDelegate::applicationDidFinishLaunching() {
	//初始化 director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLViewImpl::createWithRect("HaHaHa", Rect(0, 0, 960, 640));
        director->setOpenGLView(glview);
    }
    director->getOpenGLView()->setDesignResolutionSize(960, 640, ResolutionPolicy::SHOW_ALL);
    // 設定是否在螢幕上顯示遊戲幀數
    // 開發階段建議開啟這個設定,可以通過這個對自己遊戲性能有個大體了解
    // 等遊戲正式釋出時關閉這個設定
    director->setDisplayStats(true);
    // 設定幀率,預設值為60幀每秒
    director->setAnimationInterval(1.0 / 60);
 
    FileUtils::getInstance()->addSearchPath("res");
    // 建立一個HelloWorld的scene.這個是自動回收的對象
    auto scene = HelloWorld::createScene();
    // 告訴director運作HelloWorld的scene
    //隻有執行了這一步才能讓場景類顯示出來
    director->runWithScene(scene);
    return true;
}
           
// 當遊戲進入背景時會調用這個方法
// 比如玩遊戲時按下android手機的home按鍵
// 比如當遊戲時有電話打入直接顯示來電界面
void AppDelegate::applicationDidEnterBackground() 
{
    Director::getInstance()->stopAnimation();
}
           
//當遊戲恢複到前台運作時會調用這個方法
// 比如接電話結束是遊戲界面又恢複到前台時
void AppDelegate::applicationWillEnterForeground() 
{
    Director::getInstance()->startAnimation();
}
           

接下來看類HelloWorld

HelloWorld : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();
    virtual bool init();
    CREATE_FUNC(HelloWorld);
};
           

這裡需要注意HelloWorld 類繼承自Layer類,是以HelloWorld對象為Layer對象。該類提供了3個方法:

1.建立場景方法createScene(),供AppDelegate使用;

2.重載了Layer的init方法,對其自身進行初始化;

3..通過宏函數CREATE_FUNC建立了HelloWorld的create()方法。

//建立場景方法
Scene* HelloWorld::createScene()
{
    //建立一個自釋放的場景對象
    auto scene = Scene::create();
   //建立一個自釋放的層對象
    auto layer = HelloWorld::create();
     //把層對象添加到場景上
    scene->addChild(layer);
   //傳回這個建立的場景
    return scene;
}
           
//場景初始化方法
bool HelloWorld::init()
{
    //首先進行父類初始化
    if ( !Layer::init() )
    { //如果初始化父類失敗傳回false
        return false;
    }
     //MainScene.csb是釋出項目時生成的二進制檔案
     //通過該檔案儲存了我們編輯場景的完整資訊
    auto rootNode = CSLoader::createNode("MainScene.csb");
     //将CocoStudio編輯的場景資訊加到HelloWorld的layer上進行顯示
    addChild(rootNode);
 
    return true;
}
           

好了,最後總結一下:

1.遊戲運作是通過AppDelegate類裡的applicationDidFinishLaunching()方法中的一句director->runWithScene(scene)完成的;

2.runWithScene(scene)的這個參數scene就是HelloWorld類裡的createScene()方法傳回的一個Scene類型的場景對象;

3.但是HelloWorld類本身并不是Scene類型而是Layer類型,它在createScene()方法中建立了一個HelloWorld對象和一個Scene場景對象,将HelloWorld對象添加到Scene對象上并将Scene對象傳回;

4.HelloWorld對象通過create()方法建立,該對象為Layer類型,而create()方法是由宏函數CREATE_FUNC定義的;

5.MainScene.csb檔案儲存了在CocoStudio編輯的場景資訊,在HelloWorld對象的init()方法裡我們通過代碼CSLoader::createNode("MainScene.csb")加載該二進制檔案并添加到了HelloWorld對象上。

到這裡cocos的項目工程大家應當都熟悉了,如果哪裡有問題歡迎留言一起交流讨論哈!