最近在研究cocos2dx,由于项目中要用到内容滚动效果(内容超出容器,可以通过滑动屏幕滚动来查看),所以就毫不犹豫的选择了CCScrollView组件。
使用中发现CCScrollView的体验不佳:理论上应该是当鼠标滑动离开时,由于惯性效果,内容应该继续向前滑动一段距离。但是CCScrollView却是鼠标离开后,内容就立即停止了,并没有继续向前滑动。
通过网络搜索发现,有人说可以用CCTableView替换CCScrollView,因为CCTableView具有惯性滑动的效果。实验中发现确实是这样。
但是仅仅是为了实现滑动而采用CCTableView,感觉是浪费了。
于是我仔细对比了下CCTableView和CCScrollView的代码,发现这种惯性滑动效果其实是在CCScrollView中实现的,也就是说CCScrollView具备惯性滑动的功能。
具体实现方法是:当你使用CCScrollView的时候调用一下CCScrollView的updateInset();这个方法即可。
可以在HelloWorldScene.cpp的init函数里面添加下面的代码,测试惯性滑动效果。
CCScrollView* scrollView = CCScrollView::create();
this->addChild(scrollView);
scrollView->setPosition(ccp(50, 50));
scrollView->setDirection(kCCScrollViewDirectionVertical);
CCSprite * sp = CCSprite::create("HelloWorld.png");
sp->setAnchorPoint(ccp(0, 0));
scrollView->setContainer(sp);
scrollView->updateInset();
当然个人感觉滑动效果还是不太完美:比如当滑动到底部时应该有阻尼效果,像IOS那样的。
我看了下cocos2d-x-3.2里面的ScrollView是具备阻尼效果的。于是对比了两个文件的代码,找到了一下地方。
在 void ScrollView::onTouchMoved(Touch* touch, Event* event) 函数里面有如下内容:
float dis = 0.0f;
if (_direction == Direction::VERTICAL)
{
dis = moveDistance.y;
float pos = _container->getPosition().y;
if (!(minContainerOffset().y <= pos && pos <= maxContainerOffset().y)) {
moveDistance.y *= BOUNCE_BACK_FACTOR;
}
}
else if (_direction == Direction::HORIZONTAL)
{
dis = moveDistance.x;
float pos = _container->getPosition().x;
if (!(minContainerOffset().x <= pos && pos <= maxContainerOffset().x)) {
moveDistance.x *= BOUNCE_BACK_FACTOR;
}
}
else
{
dis = sqrtf(moveDistance.x*moveDistance.x + moveDistance.y*moveDistance.y);
float pos = _container->getPosition().y;
if (!(minContainerOffset().y <= pos && pos <= maxContainerOffset().y)) {
moveDistance.y *= BOUNCE_BACK_FACTOR;
}
pos = _container->getPosition().x;
if (!(minContainerOffset().x <= pos && pos <= maxContainerOffset().x)) {
moveDistance.x *= BOUNCE_BACK_FACTOR;
}
}
上面的粗体加斜体部分是实现阻尼效果的。BOUNCE_BACK_FACTOR是个宏在文件里有定义:#define BOUNCE_BACK_FACTOR 0.35f
改下CCScrollView对应的函数,就可以实现阻尼效果了。(用cocos2dx 3版本开发的人就不需要改了)
CCScrollView的滑动体验