ccui.ScrollView 扩展

博客讨论了如何扩展ccui.ScrollView以适应动态添加和删除道具的情况,避免全量移动节点,并在结束操作时调整Layout坐标。此外,还介绍了如何实现ScrollView的顶点缩放,确保不干扰拖动效果。虽然缺少手势缩放功能,但提到了可以单独编写工厂函数来扩展这一特性。
摘要由CSDN通过智能技术生成

大多数游戏都有背包这个东西.

道具列表通常用 ScrollView 来实现.

这个ScrollView内部有一个Layout, 滑动都是由移动这个Layout来实现.

道具摆放通常从上往下, 从左到右.

假设你有一个道具数组, 你遍历这个数组来摆放道具.

因为数组长度是已知的, 你可以计算出Layout需要的尺寸, 再把道具摆上去.

这个实现是很容易的. 但是, 如果你提前不知道数组长度, 就是不知道道具数量,

可能随时会添加道具或者删除道具.

因为cocos2dx的坐标系是左下角为原点, 因此动态增加或删除都需要把所有的道具都移动位置,

光移动Layout是不行的.

%26nbsp;

说了一堆的废话.

 1 --    增加, 删除.
 2 function scrollView:beginEditChilds(childWidth, childHeight)
 3     self.contentSize = self:getContentSize();
 4     self.childCount = #(self:getChildren());
 5     self.colCount = math.floor(self.contentSize.width / childWidth);
 6     self.childWidth = (self.contentSize.width - childWidth * self.colCount) / (self.colCount + 1) + childWidth;
 7     self.childHeight = childHeight;
 8     self.innerSize = self:getInnerContainerSize();
 9     self.innerOffsetY = self:getInnerContainerPosition().y + self.innerSize.height - self.contentSize.height;
10 end
11 
12 function scrollView:endEditChilds()
13     local rowCount = math.ceil(self.childCount / self.colCount);
14     self.innerSize.height = math.max(self.contentSize.height, rowCount * self.childHeight);
15     self:setInnerContainerSize(self.innerSize);
16     self:setInnerContainerPosition(
17         cc.p(0, math.min(0, self.contentSize.height + self.innerOffsetY - self.innerSize.height)));
18 
19     local offsetY = self.innerSize.height - self.childHeight;
20     self.childs = self:getChildren();
21     for i = self.childCount, 1, -1 do
22         local row = math.floor((i - 1) / self.colCount);
23         local col = math.floor((i - 1) % self.colCount);
24         local x = col * self.childWidth + self.childWidth * 0.5;
25         local y = row * self.childHeight + self.childHeight * 0.5;
26         self.childs[i]:setPosition(x, self.innerSize.height - y);
27         self.childs[i].__pos = i - 1;
28     end
29 end
30 
31 function scrollView:appendChild(child)
32     child:setAnchorPoint(cc.p(0.5, 0.5));
33     self.childCount = self.childCount + 1;
34     self:addChild(child);
35 end
36 
37 function scrollView:deleteChild(child)
38     self.childCount = self.childCount - 1;
39     self:removeChild(child);
40 end

scrollView 是指 ccui.ScrollView:create() 返回的对象.

可以通过一个工厂函数给对象扩展成员函数. 这个下面在贴代码.

使用方法就是, 在add, del之前调用 begin, 之后调用end.

begin和end的目的是, 避免每一次 add, del 都要全部排列节点, 并且省去了每次数值计算.

这段代码实现了ccui.ScrollView动态增加|删除子节点.

在end函数里面, 还调整了Layout的坐标, 每次修改不会察觉到Layout的坐标变化.

%26nbsp;

%26nbsp;

有些用ccui.ScrollView做城镇地图, 可以缩放, 顶点缩放.

直接缩放Layout会影响拖动效果, 这个问题直接修改引擎或者继承这个对象.

 1 float Widget::getLeftBoundary() const
 2 {
 3     return getPosition().x - getAnchorPoint().x * _contentSize.width * _scaleX;
 4 }
 5 
 6 float Widget::getBottomBoundary() const
 7 {
 8     return getPosition().y - getAnchorPoint().y * _contentSize.height * _scaleY;
 9 }
10 
11 float Widget::getRightBoundary() const
12 {
13     return getLeftBoundary() + _contentSize.width * _scaleX;
14 }
15 
16 float Widget::getTopBoundary() const
17 {
18     return getBottomBoundary() + _contentSize.height * _scaleY;
19 }

%26nbsp;

下面是顶点缩放, 直接缩放Layout会把锚点作为中心,

我们这个缩放也是以锚点作为中心, 但是会缩放的同时移动坐标, 效果就达到了.

 1 --    获取内容缩放值.
 2 function scrollView:getInnerContainerScale()
 3     return self:getInnerContainer():getScale();
 4 end
 5 
 6 --    获取内容高宽.
 7 function scrollView:getInnerContainerSize()
 8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值