cocos2d-x学习日志(7) --CCScrollView和CCTableView的使用

本文介绍如何使用 Cocos2d-x 的 CCScrollView 和 CCTableView 实现游戏帮助页面的左右滑动及列表视图效果。通过创建 GalleryLayer 和 ListViewLayer 类,演示了设置视图方向、内容尺寸、子项数量和内容等关键步骤。
 

      在游戏和应用中经常要实现左右滑动展示游戏帮助、以列表显示内容的UI效果,就像android中的Gallery和ListView。本文通过CCScrollView和CCTableView分别来实现这两个效果,基于cocos2d-x 2.0.4版本。
      首先来简单了解一下这两个东东,CCScrollView本身是一个CCLayer,而CCTableView是CCScrollView的子类,这是引擎已经帮我们封装好了的,CCTableView可以设置成横向和纵向,用它可以实现类似于Gallery和ListView的效果。


二、实现

1.添加cocos2d-x扩展库文件




2. 首先实现游戏帮助界面

(1) 创建头文件GalleryLayer.h

[cpp]  view plain copy
  1. #ifndef __HELP_SCENE_H__  
  2. #define __HELP_SCENE_H__  
  3.   
  4. #include "cocos2d.h"  
  5. #include "SimpleAudioEngine.h"  
  6. #include "cocos-ext.h"  
  7.   
  8. USING_NS_CC;  
  9. USING_NS_CC_EXT;  
  10.   
  11. class GalleryLayer : public cocos2d::CCLayer ,public CCScrollViewDelegate  
  12. {  
  13. public:  
  14.     virtual bool init();    
  15.   
  16.     void menuCloseCallback(CCObject* pSender);  
  17.   
  18.     CREATE_FUNC(GalleryLayer);  
  19.   
  20. public:  
  21.     //scrollview滚动的时候调用  
  22.     void scrollViewDidScroll(CCScrollView* view);  
  23.     //缩放的时候调用  
  24.     void scrollViewDidZoom(CCScrollView* view);  
  25.   
  26.     virtual void onEnter();  
  27.     virtual void onExit();  
  28.   
  29.     virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);  
  30.     virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);  
  31.     virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);  
  32.     virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);  
  33.   
  34. private:  
  35.     //根据手势滑动的距离和方向滚动图层  
  36.      void adjustScrollView(float offset);  
  37.      CCScrollView *m_pScrollView;  
  38.      CCPoint m_touchPoint;  
  39.      int m_nCurPage;  
  40. };  
  41.   
  42. #endif    

      类GalleryLayer继承了CCScrollViewDelegate,实现了它的两个纯虚函数,主要是为了当scrollview滚动和缩放时回调这两函数,这样我们就可以在这两函数中做相关操作了。


(2) 看源文件GalleryLayer.cpp

[cpp]  view plain copy
  1. #include "GalleryLayer.h"  
  2. #include "ListViewLayer.h"  
  3.   
  4. using namespace cocos2d;  
  5. using namespace cocos2d::extension;  
  6.   
  7. bool GalleryLayer::init()  
  8. {  
  9.     bool bRet = false;  
  10.     do  
  11.     {  
  12.        CC_BREAK_IF( !CCLayer::init() );  
  13.   
  14.        m_nCurPage = 1;  
  15.        CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();  
  16.        CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();  
  17.   
  18.        CCLayer *pLayer = CCLayer::create();  
  19.        char helpstr[30] = {0};  
  20.        for (int i = 1; i <= 3; ++ i)  
  21.        {  
  22.            memset(helpstr, 0, sizeof(helpstr));  
  23.            sprintf(helpstr,"bg_%02d.png",i);  
  24.            CCSprite *pSprite = CCSprite::create(helpstr);  
  25.            pSprite->setPosition(ccp(visibleSize.width * (i-0.5f), visibleSize.height / 2));  
  26.            pLayer->addChild(pSprite);  
  27.        }  
  28.          
  29.        m_pScrollView = CCScrollView::create(CCSizeMake(960, 640), pLayer);  
  30.        m_pScrollView->setContentOffset(CCPointZero);  
  31.        m_pScrollView->setTouchEnabled(false);  
  32.        m_pScrollView->setDelegate(this);  
  33.        m_pScrollView->setDirection(kCCScrollViewDirectionHorizontal);  
  34.        pLayer->setContentSize(CCSizeMake(960*3, 640));  
  35.   
  36.        this->addChild(m_pScrollView);  
  37.   
  38.        CCSpriteFrameCache *pCache =  CCSpriteFrameCache::sharedSpriteFrameCache();  
  39.      
  40.        pCache->addSpriteFrame(CCSpriteFrame::create("button_normal.png",CCRectMake(0, 0, 64, 64)),"button_normal.png");  
  41.        pCache->addSpriteFrame(CCSpriteFrame::create("button_selected.png",CCRectMake(0, 0, 64, 64)),"button_selected.png");  
  42.        for (int i = 1; i <= 3; ++ i)  
  43.        {  
  44.            CCSprite *pPoint = CCSprite::createWithSpriteFrameName("button_normal.png");  
  45.            pPoint->setTag(i);  
  46.            pPoint->setPosition(ccp( origin.x + (visibleSize.width - 3 * pPoint->getContentSize().width)/2 + pPoint->getContentSize().width * (i-1), origin.y + 30));  
  47.            this->addChild(pPoint);  
  48.        }  
  49.         CCSprite *pPoint = (CCSprite *)this->getChildByTag(1);  
  50.         pPoint->setDisplayFrame(pCache->spriteFrameByName("button_selected.png"));  
  51.       
  52.         bRet = true;  
  53.     }while(0);  
  54.   
  55.     return bRet;  
  56.   
  57. }  
  58.   
  59. void GalleryLayer::menuCloseCallback(CCObject* pSender)  
  60. {  
  61.   
  62. }  
  63.   
  64. void GalleryLayer::scrollViewDidScroll(cocos2d::extension::CCScrollView *view)  
  65. {  
  66.     CCLOG("scroll");  
  67. }  
  68.   
  69. void GalleryLayer::scrollViewDidZoom(cocos2d::extension::CCScrollView *view)  
  70. {  
  71.     CCLOG("zoom");  
  72. }  
  73.   
  74. void GalleryLayer::onEnter()  
  75. {  
  76.     CCLayer::onEnter();  
  77.     CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, false);  
  78. }  
  79.   
  80. void GalleryLayer::onExit()  
  81. {  
  82.     CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);  
  83.     CCLayer::onExit();  
  84.     CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames();  
  85. }  
  86.   
  87.   
  88. bool GalleryLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)  
  89. {  
  90.     m_touchPoint = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());  
  91.     return true;  
  92. }  
  93.   
  94. void GalleryLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)  
  95. {  
  96.       
  97. }  
  98.   
  99. void GalleryLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)  
  100. {  
  101.     CCPoint endPoint = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());  
  102.     float distance = endPoint.x - m_touchPoint.x;  
  103.     if(fabs(distance) > 50)  
  104.     {  
  105.         adjustScrollView(distance);  
  106.     }  
  107. }  
  108.   
  109. void GalleryLayer::ccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)  
  110. {  
  111.     CCPoint endPoint = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());  
  112.     float distance = endPoint.x - m_touchPoint.x;  
  113.     if(fabs(distance) > 50)  
  114.     {  
  115.         adjustScrollView(distance);  
  116.     }  
  117. }  
  118.   
  119. void GalleryLayer::adjustScrollView(float offset)  
  120. {  
  121.     CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();  
  122.     CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();  
  123.     CCSpriteFrameCache *pCache =  CCSpriteFrameCache::sharedSpriteFrameCache();  
  124.     CCSprite *pPoint = (CCSprite *)this->getChildByTag(m_nCurPage);  
  125.     pPoint->setDisplayFrame(pCache->spriteFrameByName("button_normal.png"));  
  126.     if (offset<0)  
  127.     {  
  128.         m_nCurPage ++;  
  129.     }else  
  130.     {  
  131.         m_nCurPage --;  
  132.     }  
  133.   
  134.     if (m_nCurPage <1)  
  135.     {  
  136.         m_nCurPage = 1;  
  137.     }  
  138.   
  139.     if(m_nCurPage > 3)  
  140.     {  
  141.         //拨动到大于第三层,添加listViewLayer  
  142.         CCLayer *pLayer = ListViewLayer::create();  
  143.         CCScene *pScene = CCScene::create();  
  144.         pScene->addChild(pLayer);  
  145.         CCDirector::sharedDirector()->replaceScene(pScene);  
  146.     }  
  147.     else  
  148.     {  
  149.         pPoint = (CCSprite *)this->getChildByTag(m_nCurPage);  
  150.         pPoint->setDisplayFrame(pCache->spriteFrameByName("button_selected.png"));  
  151.         CCPoint  adjustPos = ccp(origin.x - visibleSize.width * (m_nCurPage-1), 0);  
  152.         m_pScrollView->setContentOffset(adjustPos, true);  
  153.     }  
  154. }  
      这里一共有三张图,是从捕鱼达人中拿出来的背景图,当滚完三张图时就跳转到ListViewLayer场景去,上面的代码比较容易懂。

      首先创建一个CCLayer,包含三张背景图,设置CCLayer的ContentSize,并设置三张图片的位置然后设置CCLayer为CCScrollview的内容,并设置CCScrollView的显示区域。最后根据用户滑动的方向和距离,通过设置scrollview的setContentOffset,滚动视图。CCScrollview.h文件中封装了一个枚举类型,一共有四个方向,常用横向和纵向,这里使用了横向。

[cpp]  view plain copy
  1. typedef enum {  
  2.     kCCScrollViewDirectionNone = -1,  
  3.     kCCScrollViewDirectionHorizontal = 0,  
  4.     kCCScrollViewDirectionVertical,  
  5.     kCCScrollViewDirectionBoth  
  6. } CCScrollViewDirection;  

(3) 测试代码

AppDelegate.cpp,找到applicationDidFinishLaunching()添加,显示屏幕size

[cpp]  view plain copy
  1. //显示屏幕的size  
  2.    CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();  
  3.      
  4.    CCSize designSize = CCSizeMake(960, 640);  
  5.      
  6.    if (screenSize.height != 960)  
  7.    {  
  8.        CCSize resourceSize = CCSizeMake(960, 640);  
  9.        pDirector->setContentScaleFactor(resourceSize.height / designSize.height);  
  10.    }  
  11.      
  12.    CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);  
HelloWorldScene.cpp

[cpp]  view plain copy
  1. CCLayer *pLayer =  GalleryLayer::create();  
  2. this->addChild(pLayer);  
(4) 效果图








3.现在来实现列表展示(ListView)的效果

(1)创建ListViewLayer.h

[cpp]  view plain copy
  1. #ifndef __TABLEVIEWTESTSCENE_H__  
  2. #define __TABLEVIEWTESTSCENE_H__  
  3.   
  4. #include "cocos2d.h"  
  5. #include "cocos-ext.h"  
  6.   
  7. class ListViewLayer : public cocos2d::CCLayer, public cocos2d::extension::CCTableViewDataSource, public cocos2d::extension::CCTableViewDelegate  
  8. {  
  9. public:  
  10.     virtual bool init();    
  11.       
  12.     virtual void scrollViewDidScroll(cocos2d::extension::CCScrollView* view);  
  13.   
  14.     virtual void scrollViewDidZoom(cocos2d::extension::CCScrollView* view);  
  15.   
  16.     //处理触摸事件,可以计算点击的是哪一个子项  
  17.     virtual void tableCellTouched(cocos2d::extension::CCTableView* table, cocos2d::extension::CCTableViewCell* cell);  
  18.     //每一项的宽度和高度  
  19.     virtual cocos2d::CCSize cellSizeForTable(cocos2d::extension::CCTableView *table);  
  20.     //生成列表每一项的内容  
  21.     virtual cocos2d::extension::CCTableViewCell* tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned int idx);  
  22.     //一共多少项  
  23.     virtual unsigned int numberOfCellsInTableView(cocos2d::extension::CCTableView *table);  
  24.   
  25.     CREATE_FUNC(ListViewLayer);  
  26. };  
  27.   
  28. #endif   
(2) 源文件 ListViewLayer.cpp

[cpp]  view plain copy
  1. #include "ListViewLayer.h"  
  2.   
  3. USING_NS_CC;  
  4. USING_NS_CC_EXT;  
  5.   
  6.   
  7. bool ListViewLayer::init()  
  8. {  
  9.     bool bRet = false;  
  10.     do  
  11.     {  
  12.         CC_BREAK_IF( !CCLayer::init() );  
  13.   
  14.         CCTableView* pTableView = CCTableView::create(this, CCSizeMake(960, 640));  
  15.         pTableView->setDirection(kCCScrollViewDirectionVertical);  
  16.         pTableView->setPosition(CCPointZero);  
  17.         pTableView->setDelegate(this);  
  18.         pTableView->setVerticalFillOrder(kCCTableViewFillTopDown);  
  19.         this->addChild(pTableView);  
  20.         pTableView->reloadData();  
  21.   
  22.         bRet = true;  
  23.     }while(0);  
  24.   
  25.     return bRet;  
  26. }  
  27.   
  28.   
  29.   
  30. void ListViewLayer::tableCellTouched(CCTableView* table, CCTableViewCell* cell)  
  31. {  
  32.     CCLog("cell touched at index: %i", cell->getIdx());  
  33. }  
  34.   
  35. CCSize ListViewLayer::cellSizeForTable(CCTableView *table)  
  36. {  
  37.     return CCSizeMake(960, 120);  
  38. }  
  39.   
  40. CCTableViewCell* ListViewLayer::tableCellAtIndex(CCTableView *table, unsigned int idx)  
  41. {  
  42.     CCString *pString = CCString::createWithFormat("%d", idx);  
  43.     CCTableViewCell *pCell = table->dequeueCell();  
  44.     if (!pCell) {  
  45.         pCell = new CCTableViewCell();  
  46.         pCell->autorelease();  
  47.         CCSprite *pSprite = CCSprite::create("listitem.png");  
  48.         pSprite->setAnchorPoint(CCPointZero);  
  49.         pSprite->setPosition(CCPointZero);  
  50.         pCell->addChild(pSprite);  
  51.   
  52.         CCLabelTTF *pLabel = CCLabelTTF::create(pString->getCString(), "Arial", 20.0);  
  53.         pLabel->setPosition(CCPointZero);  
  54.         pLabel->setAnchorPoint(CCPointZero);  
  55.         pLabel->setTag(123);  
  56.         pCell->addChild(pLabel);  
  57.     }  
  58.     else  
  59.     {  
  60.         CCLabelTTF *pLabel = (CCLabelTTF*)pCell->getChildByTag(123);  
  61.         pLabel->setString(pString->getCString());  
  62.     }  
  63.   
  64.   
  65.     return pCell;  
  66. }  
  67.   
  68. unsigned int ListViewLayer::numberOfCellsInTableView(CCTableView *table)  
  69. {  
  70.     return 20;  
  71. }  
  72.   
  73.   
  74. void ListViewLayer::scrollViewDidScroll(CCScrollView *view)  
  75. {  
  76. }  
  77.   
  78. void ListViewLayer::scrollViewDidZoom(CCScrollView *view)  
  79. {  
  80. }  
(3) 效果图

      首先需要创建CCTableView,设置它的显示区域和显示方向,这里使用了纵向。设置每个子项的宽度和高度,子项的数量以及每个子项对应的内容。每个子项是一个CCTableViewCell,这里进行了优化,复用了子项对象。





参考博文:http://codingnow.cn/cocos2d-x/1024.html

源码下载地址:http://download.youkuaiyun.com/detail/zhoujianghai/4975604

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值