cocos2dx基础篇(16)——滚动视图CCScrollView

2024-08-23 20:08

本文主要是介绍cocos2dx基础篇(16)——滚动视图CCScrollView,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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

wKioL1P7LHGh4r-zAAEl3irSbeQ272.gif


【致谢】

    http://blog.csdn.net/paea_gulang/article/details/10283601

    http://bbs.firedragonpzy.com.cn/forum.php?mod=viewthread&tid=51

    http://codingnow.cn/cocos2d-x/1024.html




【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
#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
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
52
53
54
55
56
/**
  *     容器相关操作
  *     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
virual  void  scrollViewDidScroll(CCScrollView * view);    //有滚动时的响应函数
virual  void  scrollViewDidZoom(CCScrollView * view);      //有缩放时的响应函数


5、委托代理

1
2
3
4
5
6
7
8
//设置滚动视图的事件委托代理对象,一般为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
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
#include "cocos-ext.h"
using  namespace  cocos2d::extension;


    (3)让HelloWorld类继承滚动视图的委托代理接口类CCScrollViewDelegate,重写事件侦听函数。并在HelloWorld类中声明测试相关的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
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
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
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
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);
}


    运行结果:

        (A)背景滚动、附带弹性效果。

wKioL1P7fKXQMNuRABJI5nik47U808.gif

        

        (B)只能纵向滚动,附带弹性效果。

wKiom1P7e42SMvMqAAJPJRgzfNw274.gif


        (C)背包翻页、无法触摸滚动、通过按钮进行翻页。

wKiom1P7e42xh9vNAACstxmMFVE125.gif

    

这篇关于cocos2dx基础篇(16)——滚动视图CCScrollView的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1100379

相关文章

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

数据视图(AngularJS)

<!DOCTYPE html><html ng-app="home.controller"><head><meta charset="utf-8"><title>数据视图</title><link href="page/common/css/bootstrap.min.css" rel="stylesheet"><script src="page/common/js/angular.js"></

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

c++基础版

c++基础版 Windows环境搭建第一个C++程序c++程序运行原理注释常亮字面常亮符号常亮 变量数据类型整型实型常量类型确定char类型字符串布尔类型 控制台输入随机数产生枚举定义数组数组便利 指针基础野指针空指针指针运算动态内存分配 结构体结构体默认值结构体数组结构体指针结构体指针数组函数无返回值函数和void类型地址传递函数传递数组 引用函数引用传参返回指针的正确写法函数返回数组

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

【MRI基础】TR 和 TE 时间概念

重复时间 (TR) 磁共振成像 (MRI) 中的 TR(重复时间,repetition time)是施加于同一切片的连续脉冲序列之间的时间间隔。具体而言,TR 是施加一个 RF(射频)脉冲与施加下一个 RF 脉冲之间的持续时间。TR 以毫秒 (ms) 为单位,主要控制后续脉冲之前的纵向弛豫程度(T1 弛豫),使其成为显著影响 MRI 中的图像对比度和信号特性的重要参数。 回声时间 (TE)