加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2d-x 2.0版本中CCScrollView的用法

发布时间:2020-12-14 14:17:47 所属栏目:百科 来源:网络整理
导读:cocos2d-x 2.0版本之后提供了许多控件,其中就包括ScrollView,之前总结过一个简单的ScrollView,但是问题很多,比如必须是全屏,不能是一块区域,而cocos2d-x 2.0中提供的CCScrollView中,是可以设定区域的,CCScrollView做了区域的裁剪 [cpp] view plain c

cocos2d-x 2.0版本之后提供了许多控件,其中就包括ScrollView,之前总结过一个简单的ScrollView,但是问题很多,比如必须是全屏,不能是一块区域,而cocos2d-x 2.0中提供的CCScrollView中,是可以设定区域的,CCScrollView做了区域的裁剪

[cpp] view plain copy print ?
  1. <spanstyle="font-size:16px;">glScissor((GLint)screenPos.x,(GLint)screenPos.y,(GLsizei)(m_tViewSize.width*s),(GLsizei)(m_tViewSize.height*s));</span>


但是遗憾的是tests中并没有给出CCScrollView的用法,查了一些cocos2d-iphone的资料,基本用法可以实现了,简单的总结一下!


1.用途和效果

ScrollView一般用在游戏的关卡选择这种类似的场景(比如愤怒的小鸟和割绳子的关卡选择),当然,也可以用在道具店等等一些选择菜单的场景。




滑动,浏览不同关卡菜单;点击不同的菜单精灵,处理不同的事件。


2.实现

(1) 首先需要一个创建一个CCScrollView的对象和一个“Container”(可以是CCLayer或者CCNode的对象,用来存放CCScrollView中的内容),我这里放置了两个精灵菜单选项

?
    "font-size:16px;">//CCScrollView
  1. scrollView=CCScrollView::create();
  2. CCLayer*layer=CCLayer::create();
  3. CCSprite*sprite1=CCSprite::create("HelloWorld.png");
  4. CCSprite*sprite2=CCSprite::create("HelloWorld.png");
  5. layer->setAnchorPoint(CCPointZero);
  6. layer->setPosition(CCPointZero);
  7. //Menu
  8. CCMenuItemSprite*menuItem1=CCMenuItemSprite::create(sprite1,sprite1,this,menu_selector(HelloWorld::menu1Callback));
  9. menuItem1->setPosition(ccpAdd(CCPointZero,ccp(size.width/2,size.height/2)));
  10. menuItem1->setScale(0.4f);
  11. CCMenuItemSprite*menuItem2=CCMenuItemSprite::create(sprite2,sprite2,menu_selector(HelloWorld::menu2Callback));
  12. menuItem2->setPosition(ccpAdd(ccp(480,0),size.height/2)));
  13. menuItem2->setScale(0.4f);
  14. CCMenu*menu=CCMenu::create(menuItem1,menuItem2,NULL);
  15. menu->setPosition(CCPointZero);
  16. layer->addChild(menu);</span>

(2) 设置CCScrollView的显示区域

为了使ScrollView显示更灵活,CCScrollView提供了一个显示区域的设置方法,我这里设置显示区域480x320,总的大小为960x320(假设有两屏需要显示)

?
    "font-size:16px;">layer->setContentSize(CCSizeMake(960,320));
  1. scrollView->setContentSize(CCSizeMake(480,320));
  2. scrollView->setContainer(layer);</span>
这里用layer作为(1)中的container

(3) 补充,其实到这里就基本实现了CCScrollView最基本的用法,如果需要监听滑动的事件,可以继承CCScrollViewDelegate委托,实现以下两个方法

?
    "font-size:16px;">public:
  1. voidscrollViewDidScroll(CCScrollView*view);
  2. voidscrollViewDidZoom(CCScrollView*view);</span>


3.校对

这里会有一个问题,那就是当滑动结束时,经常是在两页之间,也就是图2的情况,这种体验不太好,我简单看了一下CCScrollView的源码,发现并没有相关的设置,想必是作者考虑到无法定义每页的大小尺寸,所以没有提供吧!所以,如果需要,我们要额外加一段校对的代码

所以在HelloWorld这层,继承了触摸事件的响应方法,并在ccTouchEnded()方法中校对

?
    voidHelloWorld::adjustScrollView()
  1. {
  2. //关闭CCScrollView中的自调整
  3. scrollView->unscheduleAllSelectors();
  4. intx=scrollView->getContentOffset().x;
  5. intoffset=(int)x%480;
  6. //调整位置
  7. CCPointadjustPos;
  8. //调整动画时间
  9. floatadjustAnimDelay;
  10. if(offset<-240){
  11. //计算下一页位置,时间
  12. adjustPos=ccpSub(scrollView->getContentOffset(),ccp(480+offset,0));
  13. adjustAnimDelay=(float)(480+offset)/ADJUST_ANIM_VELOCITY;
  14. }
  15. else{
  16. //计算当前页位置,时间
  17. //这里要取绝对值,否则在第一页往左翻动的时,保证adjustAnimDelay为正数
  18. float)abs(offset)/ADJUST_ANIM_VELOCITY;
  19. //调整位置
  20. scrollView->setContentOffsetInDuration(adjustPos,adjustAnimDelay);
  21. }</span>
在这里我会根据当前相对于半屏的宽度(240像素)作为判断标准,来决定滑动结束时的所在页

这里需要注意的是必须要先关闭CCScrollView的schedule方法,因为CCScrollView在最左边和最右边做了校对,但是对中间的部分没有做校对!


4.注意事项

(1) 如果需要校对这一步,HelloWorld层是需要实现触摸方法的,而触摸的优先级一定要大于CCScrollView对象(也就是说要CCScrollView对象先响应触摸事件,然后在由HelloWorld层响应),而CCScrollView默认设置的优先级是0,所以HelloWorld需要设置为大于0的值

?
    voidHelloWorld::onEnter()
  1. CCLayer::onEnter();
  2. CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(true);
  3. }</span>

(2) 这个Demo中是有一个问题的,也就是当点着菜单项滑动的时候是无效的,因为菜单的触摸事件的优先级是最高的,所以,如果真的要做这种效果,需要考虑自己来判断触摸事件的!


Demo下载

github下载

版权声明:本文为博主原创文章,未经博主允许不得转载。

上文来自:http://blog.csdn.net/onerain88/article/details/7775569/


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

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
#ifndef GALLERY_LAYER_H
#define GALLERY_LAYER_H
#include "cocos2d.h"
#include "SimpleAudioEngine.h"
#include "cocos-ext.h"
USING_NS_CC;
USING_NS_CC_EXT;
class GalleryLayer : public cocos2d::CCLayer, CCScrollViewDelegate
{
:
virtual bool init();
void menuCloseCallback(CCObject* pSender);
CREATE_FUNC(GalleryLayer);
:
//scrollview滚动的时候会调用
scrollViewDidScroll(CCScrollView* view);
//scrollview缩放的时候会调用
scrollViewDidZoom(CCScrollView* view);
virtual void onEnter();
onExit();
ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent);
ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent);
ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent);
private :
//根据手势滑动的距离和方向滚动图层
adjustScrollView( float offset);
CCScrollView *m_pScrollView;
CCPoint m_touchPoint;
int m_nCurPage;
};
#endif

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

(2) 看源文件GalleryLayer.cpp

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "GalleryLayer.h"
#include "ListViewLayer.h"
using namespace cocos2d;
cocos2d::extension;
bool GalleryLayer::init()
{
bRet = false ;
do
{
CC_BREAK_IF( !CCLayer::init() );
m_nCurPage = 1;
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
CCLayer *pLayer = CCLayer::create();
char helpstr[30] = {0};
for ( i = 1; i <= 3; ++ i)
{
memset (helpstr,153)!important; border:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-weight:bold!important; min-height:inherit!important; background:none!important">sizeof (helpstr));
sprintf "bg_%02d.png" ,i);
CCSprite *pSprite = CCSprite::create(helpstr);
pSprite->setPosition(ccp(visibleSize.width * (i-0.5f),visibleSize.height / 2));
pLayer->addChild(pSprite);
}
m_pScrollView = CCScrollView::create(CCSizeMake(960,640),pLayer);
m_pScrollView->setContentOffset(CCPointZero);
m_pScrollView->setTouchEnabled( );
m_pScrollView->setDelegate( this );
m_pScrollView->setDirection(kCCScrollViewDirectionHorizontal);
pLayer->setContentSize(CCSizeMake(960*3,640));
->addChild(m_pScrollView);
CCSpriteFrameCache *pCache = CCSpriteFrameCache::sharedSpriteFrameCache();
pCache->addSpriteFrame(CCSpriteFrame::create( "button_normal.png" );
"button_selected.png" );
i = 1; i <= 3; ++ i)
{
CCSprite *pPoint = CCSprite::createWithSpriteFrameName( );
pPoint->setTag(i);
pPoint->setPosition(ccp( origin.x + (visibleSize.width - 3 * pPoint->getContentSize().width)/2 + pPoint->getContentSize().width * (i-1),origin.y + 30));
->addChild(pPoint);
}
CCSprite *pPoint = (CCSprite *) ->getChildByTag(1);
pPoint->setDisplayFrame(pCache->spriteFrameByName( ));
bRet = true ;
} while (0);
return bRet;
}
GalleryLayer::menuCloseCallback(CCObject* pSender)
{
}
GalleryLayer::scrollViewDidScroll(cocos2d::extension::CCScrollView *view)
{
CCLOG( "scroll" );
}
GalleryLayer::scrollViewDidZoom(cocos2d::extension::CCScrollView *view)
{
"zoom" );
}
GalleryLayer::onEnter()
{
CCLayer::onEnter();
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate( );
}
GalleryLayer::onExit()
{
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate( );
CCLayer::onExit();
CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames();
}
GalleryLayer::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent)
{
m_touchPoint = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());
return true ;
}
GalleryLayer::ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent)
{
}
GalleryLayer::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent)
{
CCPoint endPoint = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());
distance = endPoint.x - m_touchPoint.x;
if ( fabs (distance) > 50)
{
adjustScrollView(distance);
}
}
GalleryLayer::ccTouchCancelled(cocos2d::CCTouch *pTouch,cocos2d::CCEvent *pEvent)
{
CCPoint endPoint = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());
distance = endPoint.x - m_touchPoint.x;
(distance) > 50)
{
adjustScrollView(distance);
}
}
GalleryLayer::adjustScrollView( offset)
{
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
CCSpriteFrameCache *pCache = CCSpriteFrameCache::sharedSpriteFrameCache();
->getChildByTag(m_nCurPage);
));
(offset<0)
{
m_nCurPage ++;
else
{
m_nCurPage --;
}
(m_nCurPage <1)
{
m_nCurPage = 1;
}
(m_nCurPage > 3)
{
CCLayer *pLayer = ListViewLayer::create();
CCScene *pScene = CCScene::create();
pScene->addChild(pLayer);
CCDirector::sharedDirector()->replaceScene(pScene);
}
else
{
pPoint = (CCSprite *) ->getChildByTag(m_nCurPage);
));
CCPoint adjustPos = ccp(origin.x - visibleSize.width * (m_nCurPage-1),0);
m_pScrollView->setContentOffset(adjustPos,monospace!important; font-size:1em!important; padding:0px!important; border:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; min-height:inherit!important; background:none!important">);
}
}

这里一共有三张图,是从捕鱼达人中拿出来的背景图,当滚完三张图时就跳转到ListViewLayer场景去,上面的代码比较容易懂。
首先创建一个CCLayer,包含三张背景图,设置CCLayer的ContentSize,并设置三张图片的位置
然后设置CCLayer为CCScrollview的内容,并设置CCScrollView的显示区域。
最后根据用户滑动的方向和距离,通过设置scrollview的setContentOffset,滚动视图。
CCScrollview.h文件中封装了一个枚举类型,一共有四个方向,常用横向和纵向,这里使用了横向。

6
typedef enum {
kCCScrollViewDirectionNone = -1,
kCCScrollViewDirectionHorizontal = 0,
kCCScrollViewDirectionVertical,
kCCScrollViewDirectionBoth
} CCScrollViewDirection;

下面来看看这部分的效果:

2. 现在来实现列表展示(ListView)的效果
(1)创建ListViewLayer.h

28
#ifndef LISTVIEW_LAYER_H
#define LISTVIEW_LAYER_H
#include "cocos-ext.h"
ListViewLayer : cocos2d::extension::CCTableViewDataSource,monospace!important; font-size:1em!important; padding:0px!important; border:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; min-height:inherit!important; background:none!important"> cocos2d::extension::CCTableViewDelegate
{
:
init();
scrollViewDidScroll(cocos2d::extension::CCScrollView* view);
scrollViewDidZoom(cocos2d::extension::CCScrollView* view);
//处理触摸事件,可以计算点击的是哪一个子项
tableCellTouched(cocos2d::extension::CCTableView* table,cocos2d::extension::CCTableViewCell* cell);
//每一项的宽度和高度
virtual cocos2d::CCSize cellSizeForTable(cocos2d::extension::CCTableView *table);
//生成列表每一项的内容
cocos2d::extension::CCTableViewCell* tableCellAtIndex(cocos2d::extension::CCTableView *table,unsigned idx);
//一共多少项
unsigned numberOfCellsInTableView(cocos2d::extension::CCTableView *table);
CREATE_FUNC(ListViewLayer);
};
ListViewLayer继承了CCTableViewDataSource和CCTableViewDelegate。这两个抽象类封装了几个有用的函数,我们在下面的源码中将实现它们。
(2)源文件 ListViewLayer.cpp

75
#include "ListViewLayer.h"
USING_NS_CC;
USING_NS_CC_EXT;
ListViewLayer::init()
{
;
do
{
CC_BREAK_IF( !CCLayer::init() );
CCTableView* pTableView = CCTableView::create( pTableView->setDirection(kCCScrollViewDirectionVertical);
pTableView->setPosition(CCPointZero);
pTableView->setDelegate( );
pTableView->setVerticalFillOrder(kCCTableViewFillTopDown);
->addChild(pTableView);
pTableView->reloadData();
;
(0);
bRet;
}
ListViewLayer::tableCellTouched(CCTableView* table,CCTableViewCell* cell)
{
CCLog( "cell touched at index: %i" }
CCSize ListViewLayer::cellSizeForTable(CCTableView *table)
{
CCSizeMake(960,120);
}
CCTableViewCell* ListViewLayer::tableCellAtIndex(CCTableView *table,monospace!important; font-size:1em!important; padding:0px!important; border:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; min-height:inherit!important; background:none!important"> idx)
{
CCString *pString = CCString::createWithFormat( "%d" CCTableViewCell *pCell = table->dequeueCell();
(!pCell) {
pCell = new CCTableViewCell();
pCell->autorelease();
CCSprite *pSprite = CCSprite::create( "listitem.png" pSprite->setAnchorPoint(CCPointZero);
pSprite->setPosition(CCPointZero);
pCell->addChild(pSprite);
CCLabelTTF *pLabel = CCLabelTTF::create(pString->getCString(),monospace!important; font-size:1em!important; padding:0px!important; color:blue!important; border:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; min-height:inherit!important; background:none!important">"Arial" pLabel->setPosition(CCPointZero);
pLabel->setAnchorPoint(CCPointZero);
pLabel->setTag(123);
pCell->addChild(pLabel);
}
else
{
CCLabelTTF *pLabel = (CCLabelTTF*)pCell->getChildByTag(123);
pLabel->setString(pString->getCString());
}
pCell;
}
unsigned ListViewLayer::numberOfCellsInTableView(CCTableView *table)
20;
ListViewLayer::scrollViewDidScroll(CCScrollView *view)
{
}
ListViewLayer::scrollViewDidZoom(CCScrollView *view)
{
首先需要创建CCTableView,设置它的显示区域和显示方向,这里使用了纵向。设置每个子项的宽度和高度,子项的数量以及每个子项对应的内容。每个子项是一个CCTableViewCell,这里进行了优化,复用了子项对象。
下面是效果图:

源码下载地址:http://download.csdn.net/detail/zhoujianghai/4975604

上文来自:http://codingnow.cn/cocos2d-x/1024.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!