好多使用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的項目工程大家應當都熟悉了,如果哪裡有問題歡迎留言一起交流讨論哈!