【转载】cocos2dx基础篇(16)——滚动视图CCScrollView

本文详细介绍了Cocos2d-x中的CCScrollView组件,包括其基本概念、使用方法及常见操作。并通过实例演示了如何实现背景滚动、限定滚动方向及通过按钮控制翻页等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【唠叨】

    本节要讲讲滚动视图CCScrollView,相信玩过手游的同学们应该对它不会陌生吧。

    例如:愤怒的小鸟的游戏场景里大大的地图,手机的屏幕肯定无法完全显示的,所以需要通过触摸滚动才能显示大地图的其他区域;排行榜中上下滑动来查看其他玩家的排名;以及手机上主界面左右滑动来切换界面等等。

    如下图为屏幕滚动,切换手机的界面。

wKioL1P7LHGh4r-zAAEl3irSbeQ272.gif

 

【致谢】

    http://blog.youkuaiyun.com/paea_gulang/article/details/10283601

 

【Demo下载】

    https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E6%BB%9A%E5%8A%A8%E8%A7%86%E5%9B%BECCScrollView 

 

【3.x】

    (1)去掉 “CC”

    (2)滚动方向

        > CCScrollViewDirection 改为强枚举 ScrollView::Direction

1
2
3
4
5
//
     HORIZONTAL      //只能横向滚动
     VERTICAL        //只能纵向滚动
     BOTH            //横向纵向都能滚动,默认方式
//

    (3)其他变化不大。

 


 

【CCScrollView】

    滚动视图类CCScrollView继承于CCLayer,故它会忽略锚点的设置,其锚点始终为(0,0)。 而我们知道CCLayer继承了触控事件CCTouch相关的函数。而CCScrollView也继承了触控函数,并将屏幕触控事件的四个函数 ccTouchesBegan、ccTouchesMoved、ccTouchesEnded、ccTouchesCancelled进行了重写并实现了 有关触摸移动相关的操作(其内部的实现代码自己看cocos2dx的源码)。这也就是为什么滚动视图CCScrollView的屏幕可以进行上下左右滚动 的原因了。

    值得注意的是:既 然CCScrollView也是一个CCLayer图层,我们都知道触控滚动的不是CCLayer图层,而是添加在图层上的那些对象。比如 CCSprite精灵、以及图层上的CCLayer等等。为了方便实现CCScrollView的滚动效果,cocos2dx引擎规定在使用 CCScrollView时,需要在它的上面添加一个用于触控滚动的容器Container,一般容器都选用CCLayer类或其扩展类(如CCLayerColor等)。而触控事件的四个函数也是针对容器Container进行操作的。

    也就是说CCScrollView实现的视图滚动,在真正意义上说是对容器Container进行滚动。

    接下来就来讲讲它的使用方法吧!

 

1、引入头文件和命名空间

1
2
3
4
//
     #include "cocos-ext.h"
     using  namespace  cocos2d::extension;
//

 

2、创建方式

    说明:有两种创建方式。对于默认的创建方式create(),会自动创建CCLayer作为滚动视图的容器,且滚动视图的可视区域的大小默认为200*200。而第二种则是可以自定义选择哪个CCLayer作为容器。

    值得注意的是:创建滚动视图之后,对于添加子节点操作scrollView->addChild(sp),实际上是将sp添加到容器container中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//
class  CCScrollView :  public  CCLayer
 
/**
  *     2种创建方式
  */
 
     //会自动创建CCLayer作为容器
     static  CCScrollView* create();
 
     //size:     滚动视图的可视区域大小
     //container:自定义滚动视图的CCLayer容器
     static  CCScrollView* create(CCSize size, CCNode* container = NULL);
 
 
     //举例
     CCLayer* scrollLayer = CCLayer::create();
     CCScrollView* scrollView = CCScrollView::create(CCSizeMake(150, 100), scrollLayer);
//

 

3、常用操作

    设置容器、尺寸大小、容器的偏移量、允许滚动的方向、放缩、以及其他属性的判断。

    注意:因为容器与滚动视图的锚点均为(0,0)。所以容器的偏移量,指容器左下角坐标相对滚动视图左下角坐标的偏移。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//
/**
  *     容器相关操作
  *     setContainer , setContentSize , setContentOffset
  */
     //设置滚动视图的容器
     void  setContainer(CCNode* pContainer);
     CCNode* getContainer();
 
     //设置容器Container的尺寸大小
     virtual  void  setContentSize( const  CCSize & size);
     virtual  const  CCSize& getContentSize()  const ;
 
     //设置容器相对滚动视图的偏移量
     //animated为是否附带滑动的动作效果,还是直接设置为新的偏移量
     //默认滑动动作为0.15秒,从旧位置滑动到新位置.
     void  setContentOffset(CCPoint offset,  bool  animated =  false );
     void  setContentOffsetInDuration(CCPoint offset,  float  dt); 
     CCPoint getContentOffset();
 
 
/**
  *     滚动视图相关操作
  *     setViewSize , setDirection , setZoomScale ,
  *     isDragging , isTouchMoved , setBounceable , setTouchEnabled
  */
     //设置滚动视图可视区域的大小
     void  setViewSize(CCSize size);
     CCSize getViewSize();
 
     //设置滚动视图允许滚动的方向
     //CCScrollViewDirection:
     //      kCCScrollViewDirectionBoth              横向纵向都能滚动,默认方式
     //      kCCScrollViewDirectionHorizontal        只能横向滚动
     //      kCCScrollViewDirectionVertical          只能纵向滚动
     virtual  void  setDirection(CCScrollViewDirection eDirection);
     CCScrollViewDirection getDirection();
 
     //放缩滚动视图大小
     //好像有bug,建议不要使用了!
     void  setZoomScale( float  s);
     void  setZoomScale( float  s,  bool  animated);
     float  getZoomScale();
     void  setZoomScaleInDuration( float  s,  float  dt);
 
     bool  isDragging();                      //用户是否正在CCScrollView中操作
     bool  isTouchMoved();                    //用户是否在CCScrollView中移动
     void  setBounceable( bool  bBounceable);   //是否开启弹性效果 
     bool  isBounceable();                    //是否具有弹性效果
     void  setTouchEnabled( bool  e);           //是否开启触摸
//

 

4、事件委托代理接口类CCScrollViewDelegate

    CCScrollViewDelegate类主要是用来侦听CCScrollView的事件,并设置事件的回调响应函数。

    使用方法:在创建CCScrollView类的CCLayer类中,让CCLayer继承CCScrollViewDelegate,并重写如下两个事件回调响应函数。

1
2
3
4
//
     virual  void  scrollViewDidScroll(CCScrollView * view);    //有滚动时的响应函数
     virual  void  scrollViewDidZoom(CCScrollView * view);      //有缩放时的响应函数
//

 

5、委托代理

1
2
3
4
5
6
7
8
9
10
//
     //设置滚动视图的事件委托代理对象,一般为this
     //并且CCLayer必需要继承代理接口类CCScrollViewDelegate
     void  setDelegate(CCScrollViewDelegate* pDelegate);
     CCScrollViewDelegate* getDelegate();
 
 
     //举例:
     //scrollView->setDelegate(this);
//

 

6、关于尺寸大小

    CCScrollView的使用过程中涉及到两个尺寸大小。

    (1)滚动视图的尺寸大小:即可视区域的大小。使用setViewSize()进行设置。

    (2)容器的尺寸大小:使用setContentSize()进行设置。

    例如设置滚动视图尺寸大小为100*100,容器的尺寸大小为1000*1000。那么每次对视图进行滚动,都只能看到容器100*100的某部分区域。

    具体图文解说可以参照cocos-孤狼大神写的:和屌丝一起学cocos2dx-CCScrollView

 

7、关于触摸滚动

    使用setDirection()可以设置滚动的方向。主要有三个类型:

    (1)横向纵向都能滚动    kCCScrollViewDirectionBoth              

    (2)只能横向滚动        kCCScrollViewDirectionHorizontal        

    (3)只能纵向滚动        kCCScrollViewDirectionVertical          

    另外setTouchEnabled()是用来设置是否开启触控事件的。所以若设置为false。那么即使setDirection()了,也无法滚动视图。

 

8、使用技巧

    (1)创建CCScrollView,和容器CCLayer;并设置滚动视图的容器为该容器。

    (2)设置容器的尺寸大小setContentSize;滚动视图(可视区域)的尺寸大小setViewSize。

    (3)将各种精灵、菜单、按钮等加入到容器中。

    (4)设置委托代理setDelegate(this),并实现回调函数。

 


 

【代码实战】

    这里例举了滚动视图CCScrollView的三种用途。

1
2
3
4
5
//
     void  test1();      //测试图片滚动
     void  test2();      //测试只能纵向滚动
     void  test3();      //测试背包翻页
//

 

1、资源图片

    第一组:

wKioL1P7dF3BNzBAAAddWYzXKxY984.jpg

    第二组:

wKioL1P7dNmj0RMeAAAjK9teRfE282.jpg    wKiom1P7c8GDVKW8AAAjtKSDM-M911.jpg    wKioL1P7dNmh99oMAAAjKsNJ2mA727.jpg    wKioL1P7dNmgUrZWAAAj3a3fdFY451.jpg

    第三组:

wKiom1P7c4-BNhddAAATWetOdzQ115.jpg    wKioL1P7dKahSmKMAAATDlDPr7M853.jpg

wKioL1P7dKfRh-XpAAATIvbAoeQ026.jpg    wKiom1P7c4-yKualAAAU7Ih-51U755.jpg    wKiom1P7c4-CHawmAAANgkMX34Q085.jpg

 

2、引入头文件和命名空间

1
2
3
4
//
     #include "cocos-ext.h"
     using  namespace  cocos2d::extension;
//

 

3、继承CCScrollViewDelegate,重写事件侦听函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//
     class  HelloWorld :  public  cocos2d::CCLayer, public  CCScrollViewDelegate
     {
     public :
         virtual  bool  init();  
         static  cocos2d::CCScene* scene();
         void  menuCloseCallback(CCObject* pSender);
         CREATE_FUNC(HelloWorld);
 
         void  test1();  //测试图片滚动
         void  test2();  //测试只能纵向滚动
         void  test3();  //测试背包翻页
 
         int  pageNumber;           //背包第几页
         CCMenuItemImage* pBack;   //往前翻页
         CCMenuItemImage* pFront;  //往后翻页
         void  scrollImage(CCObject* sender);  //test3的背包翻页
 
         void  scrollViewDidScroll(CCScrollView* view);  //滚动时响应的回调函数
         void  scrollViewDidZoom(CCScrollView* view);    //放缩时响应的回调函数
     };
//

 

4、委托代理回调函数

    在控制台输出LOG。

1
2
3
4
5
6
7
8
9
10
//
     void  HelloWorld::scrollViewDidScroll(CCScrollView* view) 
     {
         CCLOG( "ScrollView Moved!" );
     }
     void  HelloWorld::scrollViewDidZoom(CCScrollView* view) 
     {
         CCLOG( "ScrollView Scaled" );
     }
//

 

5、测试图片滚动test1()

    屏幕大小:480*320。滚动视图大小:480*320。容器大小:960*600。

    开启弹性效果setBounceable。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//
     void  HelloWorld::test1()
     {
         CCSize visableSize = CCSizeMake(480, 320);  //屏幕大小
         CCSize mysize = CCSizeMake(960,600);        //容器大小
 
     //创建容器、设置大小
         CCLayerColor* scrollLayer = CCLayerColor::create( ccc4(255,255,255,255) );
         scrollLayer->setContentSize(mysize);
         
     //容器中的东西
         CCSprite* bg = CCSprite::create( "war.png" );
         bg->setPosition( ccp(960/2.0, 600/2.0) );
         scrollLayer->addChild(bg);
 
 
     //创建滚动视图CCScrollView
         CCScrollView* scrollView = CCScrollView::create();
         this ->addChild(scrollView, 0, 1);
         
         //属性设置
         scrollView->setContainer(scrollLayer);   //设置容器
         scrollView->setViewSize( visableSize );  //可视区域大小
         scrollView->setBounceable( true );         //是否具有弹性
         
         //委托代理
         scrollView->setDelegate( this );
     }
//

 

6、测试只能纵向滚动test2()

    屏幕大小:480*320。滚动视图大小:150*100。容器大小:150*220。

    将滚动视图设置到屏幕中心位置,并设置滚动方向setDirection,只能纵向滚动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//
     void  HelloWorld::test2()
     {
         CCSize visableSize = CCSizeMake(480, 320);  //屏幕大小
         CCSize mysize = CCSizeMake(150,220);        //容器大小
 
     //创建容器、设置大小
         CCLayerColor* scrollLayer = CCLayerColor::create( ccc4(255,255,255,255) );
         scrollLayer->setContentSize(mysize);
 
     //容器中添加四个按钮
         for ( int  i = 1; i <= 4; i++) 
         {
             char  file[20];
             sprintf (file,  "btn%d.png" , i);
             CCSprite* btn = CCSprite::create(file);
             btn->setPosition( ccp(mysize.width/2, 220 - 50*i) );
             scrollLayer->addChild(btn);
         }
 
     //创建滚动视图CCScrollView
         //可视区域大小150*100 、 容器为scrollLayer
         CCScrollView* scrollView = CCScrollView::create(CCSizeMake(150, 100), scrollLayer);
         scrollView->setPosition( visableSize/2 - ccp(150/2.0, 100/2.0) );
         this ->addChild(scrollView, 0, 2);
         
         //设置为只能纵向滚动
         scrollView->setDirection(kCCScrollViewDirectionVertical);
 
         //委托代理
         scrollView->setDelegate( this );
     }
//

 

7、测试背包翻页test3()

    屏幕大小:480*320。滚动视图大小:100*80。容器大小:300*80。

    关闭触控事件setTouchEnabled(false),创建两个按钮,实现只能通过按钮进行左右翻页。

    翻页原理:通过设置容器的偏移值setContentOffset。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//
     void  HelloWorld::test3()
     {
         CCSize visableSize = CCSizeMake(480, 320);  //屏幕大小
         CCSize mysize = CCSizeMake(300,80);         //容器大小
 
     //创建容器、设置大小
         CCLayerColor* scrollLayer = CCLayerColor::create( ccc4(255,255,255,255) );
         scrollLayer->setContentSize(mysize);
 
     //容器中添加三个图片
         for ( int  i = 1; i <= 3; i++) 
         {
             char  file[20];
             sprintf (file,  "sp%d.png" , i);
             CCSprite* sp = CCSprite::create(file);
             sp->setPosition( ccp(100*i - 50, 40) );
             scrollLayer->addChild(sp);
         }
 
     //创建滚动视图CCScrollView
         //可视区域大小100*80 、 容器为scrollLayer
         CCScrollView* scrollView = CCScrollView::create(CCSizeMake(100, 80), scrollLayer);
         scrollView->setPosition( visableSize/2 - ccp(100/2.0, 0) );
         this ->addChild(scrollView, 0, 3);
 
         //属性设置
         scrollView->setTouchEnabled( false );  //关闭触碰事件,无法触摸滚动
 
         //委托代理
         scrollView->setDelegate( this );
 
 
     //创建背包翻页按钮
         //前翻pBack、后翻pFront
         pBack = CCMenuItemImage::create( "b1.png" "b2.png" "b3.png" this , menu_selector(HelloWorld::scrollImage) );
         pFront = CCMenuItemImage::create( "f1.png" "f2.png" "f3.png" this , menu_selector(HelloWorld::scrollImage) );
         pBack->setPosition( ccp(visableSize.width/2 - 100, 60) );
         pFront->setPosition( ccp(visableSize.width/2 + 100, 60) );
         CCMenu* pMenu = CCMenu::create(pBack, pFront, NULL);
         pMenu->setPosition(CCPointZero);
         this ->addChild(pMenu, 0, 100);
 
         pBack->setEnabled( false );
         pageNumber = 0;  //第0页
 
     }
 
 
     //实现翻页效果scrollImage
     void  HelloWorld::scrollImage(CCObject* sender)
     {
         CCScrollView* scrollView = (CCScrollView*) this ->getChildByTag(3);
 
         if (sender == pBack && pBack->isEnabled() )
         {
             pageNumber = max(0, pageNumber-1);  //前翻
         }
         else  if ( pFront->isEnabled() )
         {
             pageNumber = min(2, pageNumber+1);  //后翻
         }
 
         //设置容器相对滚动视图的偏移量
         scrollView->setContentOffset(ccp(-100 * pageNumber, 0),  true );
 
         pBack->setEnabled( pageNumber != 0);
         pFront->setEnabled( pageNumber != 2);
     }
//

 

8、运行结果

 

    8.1、背景滚动、附带弹性效果

wKioL1P7fKXQMNuRABJI5nik47U808.gif

        

    8.2、只能纵向滚动,附带弹性效果

wKiom1P7e42SMvMqAAJPJRgzfNw274.gif

 

    8.3、背包翻页、无法触摸滚动、通过按钮进行翻页

wKiom1P7e42xh9vNAACstxmMFVE125.gif

 

 

本文出自 “夏天的风” 博客,请务必保留此出处http://shahdza.blog.51cto.com/2410787/1544983

转载于:https://www.cnblogs.com/dudu580231/p/5642445.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值