天天看點

cocos2d-x-3.2之cpp-tests架構,cocos2d

cocos2d-x-3.2之cpp-tests架構

目錄介紹

         這個cpp-tests由于示例代碼非常多,導緻Class目錄下檔案賊多,蛤蟆截了兩次圖才截齊的。如下圖 1 ,圖 2所示

cocos2d-x-3.2之cpp-tests架構,cocos2d
cocos2d-x-3.2之cpp-tests架構,cocos2d

共58個檔案夾,外加7個頭檔案,5個 CPP檔案,非常的有規律哦。

         每個檔案夾其實基本上就是實作了 下圖3 中的一個紅框,隻是基本上。因為難免會有特裡的嘛。

cocos2d-x-3.2之cpp-tests架構,cocos2d

代碼架構

a)     第一步 main.cpp

函數從proj.win32目錄中的main.cpp開始。

第一個函數是:

int APIENTRY _tWinMain(HINSTANCEhInstance,

                       HINSTANCE hPrevInstance,

                       LPTSTR    lpCmdLine,

                      int      nCmdShow)

這個和HelloWorld項目是一模一樣的。

b)    第二步 AppDelegate.cpp

然後跳到AppDelegate.cpp檔案中的bool AppDelegate::applicationDidFinishLaunching() 函數。

這個是整個cpp-tests工程的初始化部分。我們需要很有耐心的看完,看懂這個函數後其他的都是很有規律性的了。

         這個函數首先加載一個配置檔案:

Configuration::getInstance()->loadConfigFile("configs/config-example.plist");

這個配置檔案在項目中的 Resources\configs檔案中。該檔案隻是設定了FPS(Frames Per Second),圖檔屬性等,暫時無須太多關注。

         建立一個導演,獲得視圖,獲得螢幕大小,設定視圖大小。這些對整理了解沒有太大作用。

然後是如下代碼,

auto fileUtils = FileUtils::getInstance();

std::vector<std::string> searchPaths;

if (screenSize.height > 320)

    {

        auto resourceSize =Size(960, 640);

       searchPaths.push_back("hd");

       searchPaths.push_back("ccs-res/hd");

       searchPaths.push_back("ccs-res/hd/scenetest");

       searchPaths.push_back("ccs-res/hd/scenetest/ArmatureComponentTest");

       searchPaths.push_back("ccs-res/hd/scenetest/AttributeComponentTest");

       searchPaths.push_back("ccs-res/hd/scenetest/BackgroundComponentTest");

       searchPaths.push_back("ccs-res/hd/scenetest/EffectComponentTest");

       searchPaths.push_back("ccs-res/hd/scenetest/LoadSceneEdtiorFileTest");

       searchPaths.push_back("ccs-res/hd/scenetest/ParticleComponentTest");

       searchPaths.push_back("ccs-res/hd/scenetest/SpriteComponentTest");

       searchPaths.push_back("ccs-res/hd/scenetest/TmxMapComponentTest");

       searchPaths.push_back("ccs-res/hd/scenetest/UIComponentTest");

       searchPaths.push_back("ccs-res/hd/scenetest/TriggerTest");

       searchPaths.push_back("ccs-res");

       director->setContentScaleFactor(resourceSize.height/designSize.height);

    }

    else

    {

       searchPaths.push_back("ccs-res");

       searchPaths.push_back("ccs-res/scenetest/ArmatureComponentTest");

       searchPaths.push_back("ccs-res/scenetest/AttributeComponentTest");

       searchPaths.push_back("ccs-res/scenetest/BackgroundComponentTest");

       searchPaths.push_back("ccs-res/scenetest/EffectComponentTest");

       searchPaths.push_back("ccs-res/scenetest/LoadSceneEdtiorFileTest");

       searchPaths.push_back("ccs-res/scenetest/ParticleComponentTest");

       searchPaths.push_back("ccs-res/scenetest/SpriteComponentTest");

       searchPaths.push_back("ccs-res/scenetest/TmxMapComponentTest");

       searchPaths.push_back("ccs-res/scenetest/UIComponentTest");

       searchPaths.push_back("ccs-res/scenetest/TriggerTest");

    }

//此處省略的是 給searchPaths變量指派。主要是有10個test,由于螢幕高端不同引起資源使用不同。

fileUtils->setSearchPaths(searchPaths);

這個是設定資源的查找路徑。我麼你可以看到由于高度不同,設定的資源優先級是不同的,高度高于320的時候,優先查找hd目錄下,如果小于320就不查找hd目錄。

         #if (CC_TARGET_PLATFORM ==CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM ==CC_PLATFORM_WINRT)

         根據平台不一緻,選擇不同的螢幕解決方案。

    auto scene =Scene::create();

    auto layer = new TestController();

         建立一個場景,建立一個TestControoler層.

TestController類層是在TestController.h中定義的,該類繼承Layer類。同時該類中實作了addConsoleAutoTest(); 該函數實作了控制台,用于文本輸入輸出。該類我們下一步單獨介紹。

然後将層添加上場景當中,執行該場景。

         最後判斷是否是WINRT平台,如果是的話,就擷取config-example.plist檔案的cocos2d.x.testcpp.autorun 變量時否為TRUE,如果為TRUE就啟動個自動運作。

c)      第三步TestController

對于該類,蛤蟆主要介紹其初始化幹了什麼,因為初始化會影響我們隊整個結構的了解。

我們隻看TestController::TestController() 構造函數。

首先建立一個關閉菜單。代碼如下

auto closeItem =MenuItemImage::create(s_pathClose, s_pathClose,CC_CALLBACK_1(TestController::closeCallback,this) );

    auto menu =Menu::create(closeItem,nullptr);

   menu->setPosition( Vec2::ZERO);

    closeItem->setPosition(Vec2(VisibleRect::right().x- 30,VisibleRect::top().y- 30));

         這裡CC_CALLBACK_1表示回調函數,點選該菜單後調用函數TestController::closeCallback.

其中s_pathClose 是宏定義在testResource.h 頭檔案中。如下

static const char s_pathClose[]          ="Images/close.png";

         然後設定字型類型,接着建立标簽菜單,代碼如下蛤蟆逐一解釋。

    TTFConfig ttfConfig("fonts/arial.ttf", 24);  //加載resources/fonts/目錄下的ariarl.ttf檔案。

   _itemMenu = Menu::create();//建立菜單

for (int i = 0; i < g_testCount; ++i) //for循環,g_testCount是一個g_aTestNames[]數組的數量,這個數組中每個類型是是一個結構體,一個測試用例名,一個該測試用例的函數叫做callback。

typedef struct_Controller{

const char *test_name;

std::function<TestScene*()> callback;

} Controller;

    {

        auto label =Label::createWithTTF(ttfConfig,g_aTestNames[i].test_name);//建立标簽

        auto menuItem =MenuItemLabel::create(label,CC_CALLBACK_1(TestController::menuCallback,this));//根據标簽,建立菜單項

       _itemMenu->addChild(menuItem, i + 10000);//将菜單項加入到餐單裡面

       menuItem->setPosition( Vec2( VisibleRect::center().x, (VisibleRect::top().y - (i + 1) *LINE_SPACE) )); //設定菜單項位置。

    }

   _itemMenu->setContentSize(Size(VisibleRect::getVisibleRect().size.width,(g_testCount + 1) * (LINE_SPACE)));  //設定菜單大小

   _itemMenu->setPosition(s_tCurPos);//設定菜機關置

   addChild(_itemMenu); //添加菜單到TestController層中

   addChild(menu, 1); //添加clouse菜單

最後是注冊觸屏事件,代碼如下

    auto listener =EventListenerTouchOneByOne::create();//創一個單點監聽。

   listener->setSwallowTouches(true);    //設定是否向下傳遞。

   listener->onTouchBegan = CC_CALLBACK_2(TestController::onTouchBegan,this); //觸屏按下的回調函數

listener->onTouchMoved= CC_CALLBACK_2(TestController::onTouchMoved,this);   

//觸屏滑動的回調函數

    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);//給事件添加一個事件偵聽器。

    auto mouseListener =EventListenerMouse::create();//建立滑鼠監聽器

   mouseListener->onMouseScroll = CC_CALLBACK_1(TestController::onMouseScroll,this);//滾動回調函數

   _eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener,this);//給事件添加偵聽器,_eventDispatcher 是,每個Node都有的變量,是一個事件排程器,負責排程各種事件。

d)    第四步 菜單回調函數

按下一個菜單後,菜單都會調用 void TestController::menuCallback(Ref *sender) 函數。代碼如下

         Director::getInstance()->purgeCachedData(); //purge表示清除的意思,是以這個函數意思是: 移除所有 cocos2d 緩存資料.

清除 TextureCache, SpriteFrameCache, LabelBMFont 緩存

    // get the userdata, it's the index of the menu item clicked

    automenuItem =static_cast<MenuItem *>(sender);//定義個菜單項常量

    int idx = menuItem->getLocalZOrder() - 10000;//擷取菜單項的縱坐标

    // create the test scene and run it

auto scene = g_aTestNames[idx].callback();//調用該測試用例場景的callback函數,該函數其實就是new一個測試場景而已。

    if (scene)//如果上行傳回正常,則運作該測試場景。

    {

       scene->runThisTest(); //運作該測試場景,這樣就進入了其中一個測試場景。

       scene->release();

    }

e)     第五步 測試場景TestScene

現在我們通過點選菜單進入到了測試場景中。測試場景都是繼承 TestScene, 而TestScene類是繼承Scene類。

如下圖4所示

cocos2d-x-3.2之cpp-tests架構,cocos2d

TestScene類定義在testBasic.h檔案中。主要是voidTestScene::onEnter() 函數的初始化。設定字型形式,建立一個MainMenu字型标簽如下圖5 所示,設定MainMenu菜單回調函數testScene_callback。

cocos2d-x-3.2之cpp-tests架構,cocos2d

         菜單MainMenu的回調函(testScene_callback函數),重新new一個TestController類。

f)       第六步 具體測試場景***TestScene

具體場景繼承于TestScene,相比TestScene類,多實作了一個runThisTest() 函數。

         該函數建立一個Layer層,然後将該層添加到場景中。

g)     第七步 具體測試Layer層,基類

在每個測試場景的runThisTest() 函數 中,會建立Layer層。

         真正的測試Layer層,繼承于***Test層,***Test層繼承于BaseTest層。

         例如以:

第一個菜單ActionManager中的CrashTest層,繼承于 ActionManagerTest,而ActionManagerTest繼承于 BaseTest。BaseTest繼承于Layer 層。

         BaseTest層主要定義了7個虛函數,如下。其中實作了onEnter()和onExit()函數。

    virtual std::stringtitle()const;

    virtual std::stringsubtitle()const;

         virtualvoidrestartCallback(Ref*sender);

         virtualvoidnextCallback(Ref* sender);

         virtualvoidbackCallback(Ref* sender);

    virtual voidonEnter() override;

    virtual voidonExit() override;需要在

         BaseTest層中的onEnter函數實作了

         擷取測試場景中title(該函數在ActionManagerTest中實作), 設定字型形式,添加字型到BaseTest層上。

         擷取子title(該函數在ActionManagerTest中實作),設定子titile的字型形式,添加到BaseTest層上。

         BaseTest最重要的的實作了3個菜單,并将菜單加入到BaseTest層中。

菜單如下圖 6 紅框部分所示。

cocos2d-x-3.2之cpp-tests架構,cocos2d

         三個回調函數分别是:

BaseTest::backCallback

BaseTest::restartCallback

BaseTest::nextCallback

        這三個函數在 ActionManagerTest層中實作。分别是調用上一個測試層,重新運作該測試層,調用下一個測試層。

         OK,其他測試場景都是類似的。

總結

         通過本筆記,我們知道了cpp-tests項目的總體架構。從此我們可以根據實際情況來找和版本對應的代碼了。再也不愁網上教程的代碼和我們所下載下傳版本的不一緻了。因為這個項目裡面基本包含所有你需要的代碼。