CocosUI之ScrollView
2016-04-16 14:46
811 查看
Slider滑动控件(如调节音量)
同样是一堆精灵组成这个控件外观ControlSlider* slider =
ControlSlider::create(
"ccs-res/cocosui/sliderTrack.png",
"ccs-res/cocosui/sliderProgress.png",
"ccs-res/cocosui/sliderThumb.png");
addChild(slider);
slider->setPosition(200,200);
/* 可以设置滑动范围 0——1之间 */
slider->setMinimumValue(0);
slider->setMaximumValue(1);
/* 最大和最小允许滑动范围 */
slider->setMaximumAllowedValue(.7f);
slider->setMinimumAllowedValue(.2f);
/* 设置初始位置 */
slider->setValue(.5f);
/* 设置事件监听——监听滑动状态*/
slider->addTargetWithActionForControlEvents(this, (Control::Handler)(&T020701UI::HandlerSlider),
Control::EventType::VALUE_CHANGED);
/* 回调函数*/
void HandlerSlider(Ref*
sender, Control::EventType
type)
{
ControlSlider* s = (ControlSlider*)sender;
CCLOG("called valueis %f",s->getValue());
}
ScrollView(滑动窗口)
基本使用
通常作为游戏选关的控件,用法1.ScrollView* view =
ScrollView::create(winSize); //创建一个ScrollView,参数1是显示大小,这里设置的大小是屏幕大小。参数2——Node*,是滚动的区域,参数2可以不写,create函数会自动生成——通过getContainer
view->setTag(100); //保存一下
2.Node* node =view->getContainer();//获取保存在ScrollView中的Node对象,这个Node对象是存留滑动选项的重要对象
3./*
向Node对象中添加滑动选项精灵 */
for (int i = 0; i < 9;++i)
{
char buf[128];
sprintf(buf, "Images/background%d.jpg", (i % 3) + 1);
Sprite* sprite =
Sprite::create(buf);
node->addChild(sprite);
sprite->setPosition(winSize.width / 2+ i* winSize.width, winSize.height / 2);
}
4.addChild(view); //添加这个ScrollView
//node->setContentSize(Size(winSize.width* 3, winSize.height));一定要注意,这里设置node的大小不能用node的setcontentSize
5.view->setContentSize(Size(winSize.width * 9,winSize.height));反而是用view的
6.view->setDirection(ScrollView::Direction::HORIZONTAL);
//设置滑动方向
{ /* 设置触摸滑动 */
7.
auto ev = EventListenerTouchOneByOne::create();
ev->onTouchBegan = [](Touch*,
Event*){return
true; };
ev->onTouchEnded = [&](Touch*
touch, Event*)
{
Vec2 posStart =
touch->getStartLocation();//获取按下时的位置
Vec2 posNow =
touch->getLocation();//获取当前位置
//if (posStart !=posNow) //
滑动
if(posStart.getDistanceSq(posNow) > 25)
// 如果滑动距离大于5,认为是滑动,这里用了getDistanceSq
{
CCLOG("Touchended********************");
// 启动定时器,检测container不动了
schedule(schedule_selector(T020701UI::detectScrollViewStop));
_lastXPosOfView =winSize.width * 9; //初始化位置记录器为一个不可能用的值
}
else
// 如果是点击
{
// 判断哪个图片被点击了
ScrollView* view = (ScrollView*)getChildByTag(100);
Node* node =view->getContainer();
Vec2 posNowInNode =node->convertToNodeSpace(posNow); //坐标转换
Vector<Node*>& children= node->getChildren();//获取node的所有儿子
int idx = 0;
for (Node* child : children) //遍历儿子,看看在哪个儿子里面
{
Rect rcChild =child->getBoundingBox();
if(rcChild.containsPoint(posNowInNode))
{
CCLOG("idx = %d", idx);
break;
}
idx++;
}
}
};
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(ev,this);
}
/*探查滑动是否停止如果没有停止则修正*/
voiddetectScrollViewStop(float)
{
CCLOG("detect**************************");
ScrollView* view = (ScrollView*)getChildByTag(100);
Node* node =view->getContainer();
float x = node->getPositionX();//获取node当前位置
if (_lastXPosOfView !=x) //如果每次都不想等,则说明正在滑动
{
_lastXPosOfView = x;
}
else
{
CCLOG("adjust**********************************");
// 如果_lastXPosOfView== x,说明container已经停止了
// 调整container的位置
adjustContainer();//修正位置
unschedule(schedule_selector(T020701UI::detectScrollViewStop)); //必须停止探测
}
}
float _lastXPosOfView; //位置记录器
void adjustContainer()
{
auto winSize =
Director::getInstance()->getWinSize();
ScrollView* view = (ScrollView*)getChildByTag(100);
Node* node =view->getContainer();
Vector<Node*>& children= node->getChildren();
for (auto it =children.begin(); it != children.end(); ++it)
{
Node* child = *it;
Vec2 pos =child->getPosition();//获取节点位置,这个位置就是中心位置了
Vec2 childInWorld =node->convertToWorldSpace(pos);
float dist =abs(childInWorld.x - winSize.width / 2); //只需判断当前位置和屏幕中央的距离绝对值就可以了
if (dist <winSize.width / 2)
{
MoveBy* move =
MoveBy::create(dist / 200,Vec2(winSize.width / 2 -childInWorld.x, 0)); //用动作把其移回,速度为200像素/秒,这里正好距离差可以作为移动方式
node->runAction(move);
break;
}
}
}
总结:
1. 创建ScrollView
2. 获取Node(通过获取container)——设置Node——添加精灵们(精灵们设置)——设置大小(用ScrollView的函数)
3. Add这个Node,Add这个View
4. 添加触摸(是在Ended中设置的)——先判断是滑动还是点击,如果滑动范围非常小就认为是点击。是滑动则等其滑动完(触发滑动检测和滑动调整),是点击则判定点击哪个图片
5. 滑动检测是判断node的当前位置和过去位置是否不同
6. 滑动调整是判断哪个精灵图片距离屏幕中央最近,然后将其移动到屏幕中央
7. 记得安上定时器后要删除定时
还是要注意一下getChildren返回的是引用。
我们设置的触摸并不影响ScrollView本身的触摸,因为没有做Swallow
源码(触摸)
ScrollView派生于Layer和ActionTweenDelegate类在其create函数中用initWithViewSize设置了触摸(_touches),同时还设置了一个默认Node——container
类中也有:
virtual
bool onTouchBegan(Touch *touch,
Event *event)
override;
virtual
void onTouchMoved(Touch *touch,
Event *event)
override;
virtual
void onTouchEnded(Touch *touch,
Event *event)
override;
virtual void onTouchCancelled(Touch *touch,
Event *event)
override;
其触摸按照_ touches数目为1——滑动,为2——缩放
相关文章推荐
- CocosUI之colorswitch和Slider
- CocosUI之九妹图和编辑框
- Cocos格子地图(3)
- Cocos格子地图(2)
- Cocos格子地图(1)
- cocos2dx的数据保存之UserDault
- cocos2dx+lua注册事件函数详解
- Cocos2d-x移植android增加震动效果
- cocos2d-lua 下使用protobuffer
- cocos2d_lua播放动画
- cocos2d-x自制工具07:打印cocos2d-x的节点树
- cocos2dx 压缩图片的网站/工具
- 个人初做小游戏RunRunMagic(五) 总结
- cocos模拟器已经启动 但是不能访问6010端口
- class() 高级用法 --cocos2dx- lua
- Cocos2dx 3.x的android studio项目之间.so库、资源移植
- cocos2d-x 3.x DrawNode的使用
- mac下创建cocos2d-x的android项目详细流程
- cocos2d-x3.0 macOS下配置Android开发环境以及使用cocos2d-console来新建执行project
- Cocos2d-x 3.0中 物理碰撞检测中onContactBegin回调函数不响应问题