【唠叨】

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

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

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


【致谢】

http://blog.csdn.net/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

//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、引入头文件和命名空间

//#include"cocos-ext.h"usingnamespacecocos2d::extension;//


2、创建方式

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

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

//classCCScrollView:publicCCLayer/***2种创建方式*///会自动创建CCLayer作为容器staticCCScrollView*create();//size:滚动视图的可视区域大小//container:自定义滚动视图的CCLayer容器staticCCScrollView*create(CCSizesize,CCNode*container=NULL);//举例CCLayer*scrollLayer=CCLayer::create();CCScrollView*scrollView=CCScrollView::create(CCSizeMake(150,100),scrollLayer);//


3、常用操作

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

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

///***容器相关操作*setContainer,setContentSize,setContentOffset*///设置滚动视图的容器voidsetContainer(CCNode*pContainer);CCNode*getContainer();//设置容器Container的尺寸大小virtualvoidsetContentSize(constCCSize&size);virtualconstCCSize&getContentSize()const;//设置容器相对滚动视图的偏移量//animated为是否附带滑动的动作效果,还是直接设置为新的偏移量//默认滑动动作为0.15秒,从旧位置滑动到新位置.voidsetContentOffset(CCPointoffset,boolanimated=false);voidsetContentOffsetInDuration(CCPointoffset,floatdt);CCPointgetContentOffset();/***滚动视图相关操作*setViewSize,setDirection,setZoomScale,*isDragging,isTouchMoved,setBounceable,setTouchEnabled*///设置滚动视图可视区域的大小voidsetViewSize(CCSizesize);CCSizegetViewSize();//设置滚动视图允许滚动的方向//CCScrollViewDirection://kCCScrollViewDirectionBoth横向纵向都能滚动,默认方式//kCCScrollViewDirectionHorizontal只能横向滚动//kCCScrollViewDirectionVertical只能纵向滚动virtualvoidsetDirection(CCScrollViewDirectioneDirection);CCScrollViewDirectiongetDirection();//放缩滚动视图大小//好像有bug,建议不要使用了!voidsetZoomScale(floats);voidsetZoomScale(floats,boolanimated);floatgetZoomScale();voidsetZoomScaleInDuration(floats,floatdt);boolisDragging();//用户是否正在CCScrollView中操作boolisTouchMoved();//用户是否在CCScrollView中移动voidsetBounceable(boolbBounceable);//是否开启弹性效果boolisBounceable();//是否具有弹性效果voidsetTouchEnabled(boole);//是否开启触摸//


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

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

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

//virualvoidscrollViewDidScroll(CCScrollView*view);//有滚动时的响应函数virualvoidscrollViewDidZoom(CCScrollView*view);//有缩放时的响应函数//


5、委托代理

////设置滚动视图的事件委托代理对象,一般为this//并且CCLayer必需要继承代理接口类CCScrollViewDelegatevoidsetDelegate(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的三种用途。

//voidtest1();//测试图片滚动voidtest2();//测试只能纵向滚动voidtest3();//测试背包翻页//


1、资源图片

第一组:

第二组:

第三组:


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

//#include"cocos-ext.h"usingnamespacecocos2d::extension;//


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

//classHelloWorld:publiccocos2d::CCLayer,publicCCScrollViewDelegate{public:virtualboolinit();staticcocos2d::CCScene*scene();voidmenuCloseCallback(CCObject*pSender);CREATE_FUNC(HelloWorld);voidtest1();//测试图片滚动voidtest2();//测试只能纵向滚动voidtest3();//测试背包翻页intpageNumber;//背包第几页CCMenuItemImage*pBack;//往前翻页CCMenuItemImage*pFront;//往后翻页voidscrollImage(CCObject*sender);//test3的背包翻页voidscrollViewDidScroll(CCScrollView*view);//滚动时响应的回调函数voidscrollViewDidZoom(CCScrollView*view);//放缩时响应的回调函数};//


4、委托代理回调函数

在控制台输出LOG。

//voidHelloWorld::scrollViewDidScroll(CCScrollView*view){CCLOG("ScrollViewMoved!");}voidHelloWorld::scrollViewDidZoom(CCScrollView*view){CCLOG("ScrollViewScaled");}//


5、测试图片滚动test1()

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

开启弹性效果setBounceable。

//voidHelloWorld::test1(){CCSizevisableSize=CCSizeMake(480,320);//屏幕大小CCSizemysize=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);//创建滚动视图CCScrollViewCCScrollView*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,只能纵向滚动。

//voidHelloWorld::test2(){CCSizevisableSize=CCSizeMake(480,320);//屏幕大小CCSizemysize=CCSizeMake(150,220);//容器大小//创建容器、设置大小CCLayerColor*scrollLayer=CCLayerColor::create(ccc4(255,255,255,255));scrollLayer->setContentSize(mysize);//容器中添加四个按钮for(inti=1;i<=4;i++){charfile[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、容器为scrollLayerCCScrollView*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。

//voidHelloWorld::test3(){CCSizevisableSize=CCSizeMake(480,320);//屏幕大小CCSizemysize=CCSizeMake(300,80);//容器大小//创建容器、设置大小CCLayerColor*scrollLayer=CCLayerColor::create(ccc4(255,255,255,255));scrollLayer->setContentSize(mysize);//容器中添加三个图片for(inti=1;i<=3;i++){charfile[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、容器为scrollLayerCCScrollView*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、后翻pFrontpBack=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页}//实现翻页效果scrollImagevoidHelloWorld::scrollImage(CCObject*sender){CCScrollView*scrollView=(CCScrollView*)this->getChildByTag(3);if(sender==pBack&&pBack->isEnabled()){pageNumber=max(0,pageNumber-1);//前翻}elseif(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、背景滚动、附带弹性效果

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


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