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

共58個檔案夾,外加7個頭檔案,5個 CPP檔案,非常的有規律哦。
每個檔案夾其實基本上就是實作了 下圖3 中的一個紅框,隻是基本上。因為難免會有特裡的嘛。
代碼架構
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所示
TestScene類定義在testBasic.h檔案中。主要是voidTestScene::onEnter() 函數的初始化。設定字型形式,建立一個MainMenu字型标簽如下圖5 所示,設定MainMenu菜單回調函數testScene_callback。
菜單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 紅框部分所示。
三個回調函數分别是:
BaseTest::backCallback
BaseTest::restartCallback
BaseTest::nextCallback
這三個函數在 ActionManagerTest層中實作。分别是調用上一個測試層,重新運作該測試層,調用下一個測試層。
OK,其他測試場景都是類似的。
總結
通過本筆記,我們知道了cpp-tests項目的總體架構。從此我們可以根據實際情況來找和版本對應的代碼了。再也不愁網上教程的代碼和我們所下載下傳版本的不一緻了。因為這個項目裡面基本包含所有你需要的代碼。