• Cocos2d-x 2.0 TestCpp框架源码分析


        好的引擎,会提供一系列完整的功能示例,Cocos2d-x之所以能得到很多人的喜爱,其重要的原因是它提供了丰富而易学的示例。在cocos2d-2.0-x-2.0.2中这些示例被放在一个名叫TestCpp的工程中,为了更好的学习Cocos2d-x的功能示例,我们今天来学习一下这个工程的框架结构。


             在VS的解决方案里展开TestCpp工程,其下有43个示例目录,除此之前还有几个文件:

     

    AppDelegate.h/cpp : 程序控制类AppDelegate 。

    controller.h/cpp:示例场景管理类TestController,用于显示所有示例的菜单。

    testBasic.h/cpp:示例场景基类TestScene,用于返回到主界面场景。

    testResource.h:文件资源名称字符串定义头文件

    tests.h:示例总头文件

    main.h/cpp:主函数及头文件

     

              所有的示例都是写在单独的由TestScene派生场景类中,在这些场景中加入一些由CCLayer派生的示例对象来实现相应功能的展示。

     

              与HelloWorld一样,我们需要在main.cpp中创建AppDelegate实例,并设置窗口大小,启动游戏程序。

    1. #include "main.h"  
    2. #include "AppDelegate.h"  
    3. #include "CCEGLView.h"  
    4. USING_NS_CC;  
    5. //WIN32程序主函数  
    6. int APIENTRY _tWinMain(HINSTANCE hInstance,  
    7.                        HINSTANCE hPrevInstance,  
    8.                        LPTSTR    lpCmdLine,  
    9.                        int       nCmdShow)  
    10. {  
    11.     UNREFERENCED_PARAMETER(hPrevInstance);  
    12.     UNREFERENCED_PARAMETER(lpCmdLine);  
    13.     //实例化一个Cocos2d-x程序对象  
    14.     AppDelegate app;  
    15.     //创建OpenGL视窗并设置窗口大小  
    16.     CCEGLView* eglView = CCEGLView::sharedOpenGLView();  
    17.     eglView->setFrameSize(480, 320);  
    18.     //运行程序对象  
    19.     return CCApplication::sharedApplication()->run();  
    20. }  

     

        在AppDelegate.cpp中的boolAppDelegate::applicationDid。FinishLaunching()函数中创建场景并运行场景

    1. bool AppDelegate::applicationDidFinishLaunching()  
    2. {  
    3.     // 取得当前显示设备指针并设置其OpenGL视窗  
    4.     CCDirector *pDirector = CCDirector::sharedDirector();  
    5.     pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());  
    6.     //取得当前运行硬件平台  
    7.     TargetPlatform target = getTargetPlatform();  
    8.     //如果是IPAD  
    9.     if (target == kTargetIpad)  
    10.     {  
    11.         //如果能启动高清屏,使用高精度资源,否则使用一般精度资源  
    12.         if (pDirector->enableRetinaDisplay(true))  
    13.         {  
    14.             CCFileUtils::sharedFileUtils()->setResourceDirectory("ipadhd");  
    15.         }  
    16.         else   
    17.         {  
    18.             CCFileUtils::sharedFileUtils()->setResourceDirectory("ipad");  
    19.         }  
    20.     }  
    21.     //如果是Iphone  
    22.     else if (target == kTargetIphone)  
    23.     {  
    24.         //如果能启动高清屏,使用高精度资源  
    25.         if (pDirector->enableRetinaDisplay(true))  
    26.         {  
    27.             CCFileUtils::sharedFileUtils()->setResourceDirectory("hd");  
    28.         }  
    29.     }  
    30.   
    31.     // 设置FPS信息显示  
    32.     pDirector->setDisplayStats(true);  
    33.   
    34.     //设置帧间隔时间  
    35.     pDirector->setAnimationInterval(1.0 / 60);  
    36.     //在这里创建一个场景  
    37.     CCScene * pScene = CCScene::create();  
    38.     //实例化一个TestController,它是一个CCLayer。  
    39.     CCLayer * pLayer = new TestController();  
    40.     //设置由内存管理器来进行自动回收,不必手动DELETE  
    41.     pLayer->autorelease();  
    42.     //将它放置到场景中  
    43.     pScene->addChild(pLayer);  
    44.     //运行这个新创建的场景。  
    45.     pDirector->runWithScene(pScene);  
    46.   
    47.     return true;  
    48. }  

     

        下面我们来看一下testBase.h/cpp,这里面有一个所有示例都要用到的场景基类TestScene。

    1. #ifndef _TEST_BASIC_H_  
    2. #define _TEST_BASIC_H_  
    3. //Cocos2d头文件  
    4. #include "cocos2d.h"  
    5. //使用Cocos2d命名空间  
    6. USING_NS_CC;  
    7. using namespace std;  
    8.   
    9. class TestScene : public CCScene  
    10. {  
    11. public:   
    12.     //构造  
    13.     TestScene(bool bPortrait = false);  
    14.     //场景被加载时的回调函数  
    15.     virtual void onEnter();  
    16.     //自定义的虚函数,用于运行场景。  
    17.     virtual void runThisTest() = 0;  
    18.     //返回主界面的菜单按钮响应回调函数。  
    19.     virtual void MainMenuCallback(CCObject* pSender);  
    20. };  
    21.   
    22. #endif  

    cpp文件:


    1. #include "testBasic.h"  
    2. #include "controller.h"  
    3. //构造函数  
    4. TestScene::TestScene(bool bPortrait)  
    5. {  
    6.       
    7.     CCScene::init();  
    8. }  
    9. //场景被加载时的回调函数  
    10. void TestScene::onEnter()  
    11. {  
    12.     CCScene::onEnter();  
    13.   
    14.       //#if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)  
    15. //    CCLabelBMFont* label = CCLabelBMFont::create("MainMenu",  "fonts/arial16.fnt");  
    16. //#else  
    17.     //创建一个文字标签,显示“MainMenu”字符串  
    18.     CCLabelTTF* label = CCLabelTTF::create("MainMenu""Arial", 20);  
    19. //#endif  
    20.     //增加一个菜单标签,设定其被按下时的回调函数,用于返回到主界面  
    21.     CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(TestScene::MainMenuCallback));  
    22.     //将菜单标签加入创建的菜单中,并设置相应位置。  
    23.     CCMenu* pMenu =CCMenu::create(pMenuItem, NULL);  
    24.     CCSize s = CCDirector::sharedDirector()->getWinSize();  
    25.     pMenu->setPosition( CCPointZero );  
    26.     pMenuItem->setPosition( CCPointMake( s.width - 50, 25) );  
    27.     //将菜单放入场景中。  
    28.     addChild(pMenu, 1);  
    29. }  
    30. //菜单标签被按下时的响应函数  
    31. void TestScene::MainMenuCallback(CCObject* pSender)  
    32. {  
    33.     //新创建一个场景。  
    34.     CCScene* pScene = CCScene::create();  
    35.     //新创建一个TestController对象  
    36.     CCLayer* pLayer = new TestController();  
    37.     pLayer->autorelease();  
    38.     //将它放入新创建的场景中并运行。  
    39.     pScene->addChild(pLayer);  
    40.     CCDirector::sharedDirector()->replaceScene(pScene);  
    41. }  

     

             在TestScene中,提供了一个可以被点击的标签MainMenu,从字面意思就知道点击它可以返回主菜单界面,这个主菜单在哪呢?就是TestController。

    1. #ifndef _CONTROLLER_H_  
    2. #define _CONTROLLER_H_  
    3.   
    4. #include "cocos2d.h"  
    5.   
    6. USING_NS_CC;  
    7.   
    8. class TestController : public CCLayer  
    9. {  
    10. public:  
    11.     //构造  
    12.     TestController();  
    13.     //析构  
    14.     ~TestController();  
    15.     //菜单项响应回调函数  
    16.     void menuCallback(CCObject * pSender);  
    17.     //关闭程序响应回调函数  
    18.     void closeCallback(CCObject * pSender);  
    19.     //按下触点响应函数。  
    20.     virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);  
    21.     //按下状态移动触点响应函数。  
    22.     virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);  
    23.   
    24. private:  
    25.     //接下状态移动触点的开始位置  
    26.     CCPoint m_tBeginPos;  
    27.     //主菜单  
    28.     CCMenu* m_pItemMenu;  
    29. };  
    30.   
    31. #endif  
    进入Cpp看一下:
    1. #include "controller.h"  
    2. #include "testResource.h"  
    3. #include "tests.h"  
    4. //菜单项的行间距 ,设40点  
    5. #define LINE_SPACE          40  
    6. //创建一个当前触点位置变量,初始化为左下角位置。  
    7. static CCPoint s_tCurPos = CCPointZero;  
    8. //创建指定的示例场景  
    9. static TestScene* CreateTestScene(int nIdx)  
    10. {  
    11.     //先清空一下显示设备使用的数据  
    12.     CCDirector::sharedDirector()->purgeCachedData();  
    13.   
    14.     //定义TestScene指针用于接收创建的示例场景  
    15.     TestScene* pScene = NULL;  
    16.     //跟据参数来创建相应的TestScene派生类对象。  
    17.     switch (nIdx)  
    18.     {  
    19.     case TEST_ACTIONS://动画处理  
    20.         pScene = new ActionsTestScene(); break;  
    21.     case TEST_TRANSITIONS://场景切换  
    22.         pScene = new TransitionsTestScene(); break;  
    23.      case TEST_PROGRESS_ACTIONS://进度动画控制  
    24.          pScene = new ProgressActionsTestScene(); break;  
    25.     case TEST_EFFECTS://特效演示  
    26.         pScene = new EffectTestScene(); break;  
    27.     case TEST_CLICK_AND_MOVE://拖动演示  
    28.         pScene = new ClickAndMoveTestScene(); break;  
    29.     case TEST_ROTATE_WORLD://旋转CCLayer  
    30.         pScene = new RotateWorldTestScene(); break;  
    31.     case TEST_PARTICLE://粒子系统  
    32.         pScene = new ParticleTestScene(); break;  
    33.     case TEST_EASE_ACTIONS://多样化运动动画  
    34.         pScene = new ActionsEaseTestScene(); break;  
    35.     case TEST_MOTION_STREAK://拖尾动画效果  
    36.         pScene = new MotionStreakTestScene(); break;  
    37.     case TEST_DRAW_PRIMITIVES://基本图形绘制  
    38.         pScene = new DrawPrimitivesTestScene(); break;  
    39.     case TEST_COCOSNODE://结点控制  
    40.         pScene = new CocosNodeTestScene(); break;  
    41.     case TEST_TOUCHES://触屏处理  
    42.         pScene = new PongScene(); break;  
    43.     case TEST_MENU://菜单处理  
    44.         pScene = new MenuTestScene(); break;  
    45.     case TEST_ACTION_MANAGER://动画管理  
    46.         pScene = new ActionManagerTestScene(); break;  
    47.     case TEST_LAYER://CCLayer功能展示  
    48.         pScene = new LayerTestScene(); break;  
    49.     case TEST_SCENE://CCScene功能展示  
    50.         pScene = new SceneTestScene(); break;  
    51.     case TEST_PARALLAX://视角控制  
    52.         pScene = new ParallaxTestScene(); break;  
    53.     case TEST_TILE_MAP://基于格子的地图  
    54.         pScene = new TileMapTestScene(); break;  
    55.     case TEST_INTERVAL://时间控制  
    56.         pScene = new IntervalTestScene(); break;  
    57.     case TEST_CHIPMUNKACCELTOUCH://ChipMunk物理引擎与多点触屏  
    58. #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)  
    59.         pScene = new ChipmunkAccelTouchTestScene(); break;  
    60. #else  
    61. #ifdef MARMALADEUSECHIPMUNK  
    62. #if    (MARMALADEUSECHIPMUNK == 1)  
    63.         pScene = new ChipmunkAccelTouchTestScene();   
    64. #endif  
    65.         break;  
    66. #endif  
    67. #endif  
    68.     case TEST_LABEL://文字标签  
    69.         pScene = new AtlasTestScene(); break;  
    70.     case TEST_TEXT_INPUT://输入处理  
    71.         pScene = new TextInputTestScene(); break;  
    72.     case TEST_SPRITE://精灵功能展示  
    73.         pScene = new SpriteTestScene(); break;  
    74.     case TEST_SCHEDULER://动画的时间调度  
    75.         pScene = new SchedulerTestScene(); break;  
    76.     case TEST_RENDERTEXTURE://渲染到纹理  
    77.         pScene = new RenderTextureScene(); break;  
    78.     case TEST_TEXTURE2D://纹理功能展示  
    79.         pScene = new TextureTestScene(); break;  
    80.     case TEST_BOX2D://Box2D物理引擎展示  
    81.         pScene = new Box2DTestScene(); break;  
    82.     case TEST_BOX2DBED: //Box2D物理引擎展示[物体的固定与连接]  
    83.         pScene = new Box2dTestBedScene(); break;  
    84.     case TEST_EFFECT_ADVANCE://高级屏幕效果  
    85.         pScene = new EffectAdvanceScene(); break;  
    86.     case TEST_ACCELEROMRTER://加速度  
    87.         pScene = new AccelerometerTestScene(); break;  
    88. #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA)  
    89.     case TEST_KEYPAD://键区处理  
    90.         pScene = new KeypadTestScene(); break;  
    91. #endif  
    92.     case TEST_COCOSDENSHION://声效控制  
    93.         pScene = new CocosDenshionTestScene(); break;  
    94.     case TEST_PERFORMANCE://性能测试  
    95.         pScene = new PerformanceTestScene(); break;  
    96.     case TEST_ZWOPTEX://ZWOPTEX动国  
    97.         pScene = new ZwoptexTestScene(); break;  
    98. #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)  
    99. // bada don't support libcurl  
    100. #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA)  
    101.     case TEST_CURL://网络通信基本演示  
    102.         pScene = new CurlTestScene(); break;  
    103. #endif  
    104. #endif  
    105.     case TEST_USERDEFAULT://用户日志保存示例  
    106.         pScene = new UserDefaultTestScene(); break;  
    107.     case TEST_BUGS://BUG示例  
    108.         pScene = new BugsTestScene(); break;  
    109.     case TEST_FONTS://字体演示  
    110.         pScene = new FontTestScene(); break;  
    111.     case TEST_CURRENT_LANGUAGE://获取当前语言  
    112.         pScene = new CurrentLanguageTestScene(); break;  
    113. #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)  
    114.     case TEST_TEXTURECACHE: pScene = new TextureCacheTestScene(); break;  
    115. #endif  
    116.     case TEST_EXTENSIONS:  
    117.         {   //更多扩展实例  
    118.             pScene = new ExtensionsTestScene();  
    119.         }  
    120.         break;  
    121.     case TEST_SHADER://使用Shader的渲染演示  
    122.         pScene = new ShaderTestScene();  
    123.         break;  
    124.     case TEST_MUTITOUCH://多点触屏  
    125.         pScene = new MutiTouchTestScene();  
    126.         break;  
    127.     default:  
    128.         break;  
    129.     }  
    130.     //返回创建的场景  
    131.     return pScene;  
    132. }  
    133. //构造函数  
    134. TestController::TestController()  
    135. : m_tBeginPos(CCPointZero)  
    136. {  
    137.     // 加入一个关闭菜单按钮  
    138.     CCMenuItemImage *pCloseItem = CCMenuItemImage::create(s_pPathClose, s_pPathClose, this, menu_selector(TestController::closeCallback) );  
    139.     //创建一个菜单放置关闭按钮  
    140.     CCMenu* pMenu =CCMenu::create(pCloseItem, NULL);  
    141.     CCSize s = CCDirector::sharedDirector()->getWinSize();  
    142.     //设置这个菜单位置  
    143.     pMenu->setPosition( CCPointZero );  
    144.     pCloseItem->setPosition(CCPointMake( s.width - 30, s.height - 30));  
    145.   
    146.     //新建一个测试项菜单,将所有代表测试场景的菜单标签项加入菜单  
    147.     m_pItemMenu = CCMenu::create();  
    148.     //  
    149.     for (int i = 0; i < TESTS_COUNT; ++i)  
    150.     {  
    151. // #if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)  
    152. //         CCLabelBMFont* label = CCLabelBMFont::create(g_aTestNames[i].c_str(),  "fonts/arial16.fnt");  
    153. // #else  
    154.         CCLabelTTF* label = CCLabelTTF::create(g_aTestNames[i].c_str(), "Arial", 24);  
    155. // #endif          
    156.         CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(TestController::menuCallback));  
    157.         //将代表测试场景的菜单标签加入菜单中,以i+10000的值做为Z值。  
    158.         m_pItemMenu->addChild(pMenuItem, i + 10000);  
    159.         //设置代表测试场景的菜单标签在测试项菜单层的位置  
    160.         pMenuItem->setPosition( CCPointMake( s.width / 2, (s.height - (i + 1) * LINE_SPACE) ));  
    161.     }  
    162.     //设置测试项菜单的大小  
    163.     m_pItemMenu->setContentSize(CCSizeMake(s.width, (TESTS_COUNT + 1) * (LINE_SPACE)));  
    164.     //设置测试项菜单的位置  
    165.     m_pItemMenu->setPosition(s_tCurPos);  
    166.     //将测试项菜单放入当前CCLayer  
    167.     addChild(m_pItemMenu);  
    168.     //设置开启触屏事件响应  
    169.     setTouchEnabled(true);  
    170.     //将关闭按钮项菜单放入当前CCLayer  
    171.     addChild(pMenu, 1);  
    172.   
    173. }  
    174.   
    175. TestController::~TestController()  
    176. {  
    177. }  
    178. //点击菜单项的事件响应函数  
    179. void TestController::menuCallback(CCObject * pSender)  
    180. {  
    181.     // 取得菜单项  
    182.     CCMenuItem* pMenuItem = (CCMenuItem *)(pSender);  
    183.     //取得Z值,减10000算出是第几个菜单项  
    184.     int nIdx = pMenuItem->getZOrder() - 10000;  
    185.   
    186.     //创建相应的场景  
    187.     TestScene* pScene = CreateTestScene(nIdx);  
    188.     if (pScene)  
    189.     {  
    190.         //运行当前测试场景  
    191.         pScene->runThisTest();  
    192.         //runThisTest中会对其引用计数加1变为2,这里做一次引用计数减1操作,以保证后面再释放场景时可以正常的释放。  
    193.         pScene->release();  
    194.     }  
    195. }  
    196. //点击关闭按钮时的响应处理  
    197. void TestController::closeCallback(CCObject * pSender)  
    198. {  
    199.     //退出程序  
    200.     CCDirector::sharedDirector()->end();  
    201. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)  
    202.     exit(0);  
    203. #endif  
    204. }  
    205. //触点按下时的响应处理  
    206. void TestController::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)  
    207. {  
    208.     //获取第一个触点位置  
    209.     CCSetIterator it = pTouches->begin();  
    210.     CCTouch* touch = (CCTouch*)(*it);  
    211.     //将位置保存到变量m_tBeginPos中。  
    212.     m_tBeginPos = touch->getLocation();      
    213. }  
    214. //触点  
    215. void TestController::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)  
    216. {  
    217.     //获取第一个触点位置  
    218.     CCSetIterator it = pTouches->begin();  
    219.     CCTouch* touch = (CCTouch*)(*it);  
    220.     //取得这个位置与上一帧移动的Y值之差,即在纵方向的偏移。  
    221.     CCPoint touchLocation = touch->getLocation();      
    222.     float nMoveY = touchLocation.y - m_tBeginPos.y;  
    223.     //计算菜单在纵方向上也移动相应值后的新位置。  
    224.     CCPoint curPos  = m_pItemMenu->getPosition();  
    225.     CCPoint nextPos = ccp(curPos.x, curPos.y + nMoveY);  
    226.     //这里对新位置的有效范围做个限定  
    227.     CCSize winSize = CCDirector::sharedDirector()->getWinSize();  
    228.     if (nextPos.y < 0.0f)  
    229.     {  
    230.         m_pItemMenu->setPosition(CCPointZero);  
    231.         return;  
    232.     }  
    233.   
    234.     if (nextPos.y > ((TESTS_COUNT + 1)* LINE_SPACE - winSize.height))  
    235.     {  
    236.         m_pItemMenu->setPosition(ccp(0, ((TESTS_COUNT + 1)* LINE_SPACE - winSize.height)));  
    237.         return;  
    238.     }  
    239.     //更新菜单到新位置  
    240.     m_pItemMenu->setPosition(nextPos);  
    241.     //记录当前位置为旧位置。  
    242.     m_tBeginPos = touchLocation;  
    243.     s_tCurPos   = nextPos;  
    244. }  

             总结:示例框架展示了一个菜单,每个菜单项代表了一个示例工程,菜单项的Z值是递增排列的。点击菜单项响应TestController::menuCallback函数,此函数通过减去Z值基数可以取得菜单项的索引,并通过CreateTestScene(nIdx);来创建出相应的示例场景。本示例框架还演示了如何在纵方向上拖动一个菜单。


          

  • 相关阅读:
    codeforces 616E. Sum of Remainders 数学
    codeforces 620F. Xors on Segments
    codeforces 417D. Cunning Gena 状压dp
    bzoj 1934 : [Shoi2007]Vote 善意的投票 最小割
    codeforces 628F. Bear and Fair Set 网络流
    codeforces 626E. Simple Skewness 三分
    div嵌套,内层的margin-top会跑到外层
    测试用导航(为了方便在各个测试页面间进行跳转,只需将此js代码引入每个页面即可) V2.0
    ECS_8080端口连接拒绝问题排查
    京东技术架构(二)构建需求响应式亿级商品详情页
  • 原文地址:https://www.cnblogs.com/Anzhongliu/p/6091970.html
Copyright © 2020-2023  润新知