按照惯例先发上效果图:

正文:

一说起滚动效果大家可能会联想到Cocos2d-x给我们提供的ScrollView。我一开始也是打算用ScrollView来实现的,但是用着用着发现出现了各种莫名其妙的错误,所以只好自己重新写一个Node,通过onTouchBegan和onTouhMoved两个事件回调来实现滚动的效果。


GridView使用说明:

1.利用GridView::create(int row,int column)来创建一个GridView,row和column分别指定行数和列数。注意这里的行数是指可见的行数

2.通过GridView::addItem(Node* node)来向GridView里面添加元素


GridView实现思路:

1.创建的时候指定行数和列数

2.GridView里面新建一个Node(visibleNode)用于保存所有的item(以后实现滚动的时候方便点)

3.通过addItem进GridView时,计算出item的位置(x,y)

4.接受触摸事件

5.计算触摸的偏移量,visibleNode移动相应的距离

6.一头一尾的触摸要稍作判断(即不能上方出现空白或全空白)

7.添加遮罩层


核心代码解析:

1、添加Item

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
43
44
45
46
47
48
49
50
void GridView::addItem(Node*item){
if (getItemSize()==0){<spanstyle= "white-space:pre" ></span> //如果是第一个Item(则以这个item为标准)
m_visible_node=Node::create();<spanstyle= "white-space:pre" ></span> //visibleNode用于保存所有的item
m_visible_node->setAnchorPoint(Point(0,0));
m_visible_node_posy_max=0;<spanstyle= "white-space:pre" ></span> //m_visible_posy_max表示现在最大能移上去多少(对应于尾的判断)
m_item_width=item->getContentSize().width;<spanstyle= "white-space:pre" ></span> //利用第一个Item来确定标准
m_item_height=item->getContentSize().height;
this ->setContentSize(
Size(m_item_width*m_column_num,m_item_height*m_row_num)
);
m_visible_node->setContentSize(
Size(m_item_width*m_column_num,m_item_height*m_row_num)
);
ClippingNode*cliper=ClippingNode::create();<spanstyle= "white-space:pre" ></span> //遮罩层
DrawNode*drawNode=DrawNode::create();
Pointpoints[]={Point(getPosition()),
Point(getPositionX(),getPositionY()+m_row_num*m_item_height),
Point(getPositionX()+m_column_num*m_item_width,
Point(getPositionX()+m_column_num*m_item_width,getPositionY())};
drawNode->drawpolygon(points,4,Color4F(0,1),0));
LayerColor*stencil=LayerColor::create(Color4B(0x00,0x00,0xC0), this ->getContentSize().width, this ->getContentSize().height);
stencil->setAnchorPoint(Point(0,0));
cliper->setStencil(stencil);
cliper->addChild(m_visible_node);
this ->addChild(cliper);
scrollbar=ScrollBar::create(m_row_num*m_item_height);<spanstyle= "white-space:pre" ></span> //滚动条(下面会讲到可以先跳过)
scrollbar->setPosition(m_item_width*m_column_num,0);
this ->addChild(scrollbar);
}
item->setAnchorPoint(Point(0,1));
int index=getItemSize()+1;
float x=(index-1)%m_column_num*m_item_width;<spanstyle= "white-space:pre" ></span> //计算出item的x,y
float y=m_item_height*m_row_num-((index-1)/m_column_num*m_item_height);
item->setPosition(Point(x,y));
int cur_max_row=(index-1)/m_column_num+1;
if (cur_max_row>m_row_num){<spanstyle= "white-space:pre" ></span> //如果当前最大行数超过可见行
m_visible_node_posy_max=(cur_max_row-m_row_num)*m_item_height;<spanstyle= "white-space:pre" ></span> //设置最大能移上去多少
scrollbar->setButtonSize(m_row_num*1.0/cur_max_row);<spanstyle= "white-space:pre" ></span>
}
m_visible_node->addChild(item);<spanstyle= "white-space:pre" ></span> //添加到visibleNode里面
m_items.insert(index,item);
}


2、触摸事件

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
bool GridView::onTouchBegan(Touch*pTouch,Event*pEvent){
Pointp=Director::getInstance()->convertToGL(pTouch->getLocationInView());
if ( this ->getBoundingBox().containsPoint(p)){<spanstyle= "white-space:pre" ></span> //判断是否触摸到
move_began=p;
return true ;
}
return false ;
}
void GridView::onTouchMoved(Touch*pTouch,Event*pEvent){
cclOG( "TouchMoved" );
move_ing=Director::getInstance()->convertToGL(pTouch->getLocationInView());
if (! this ->getBoundingBox().containsPoint(move_ing)) return ;
float offset_y=move_ing.y-move_began.y; //计算出偏移量
cclOG( "move_y:%f" ,offset_y);
m_visible_node->setPositionY(m_visible_node->getPositionY()+offset_y); //visibleNode移动相应的偏移量
if (m_visible_node->getPositionY()<0){<spanstyle= "white-space:pre" ></span> //头的判断(因为整个GridView的AnchorPoint是(0,0))
m_visible_node->setPositionY(0);
}
if (m_visible_node->getPositionY()>m_visible_node_posy_max){ //尾的判断。前面已经计算出最大可以上移的高度
m_visible_node->setPositionY(m_visible_node_posy_max);
}
if (m_visible_node_posy_max>0){<spanstyle= "white-space:pre" ></span> //这里主要是用在滚动条
float delta_y=m_visible_node->getPositionY();
float percent=delta_y/m_visible_node_posy_max;
scrollbar->setButtonPos(percent);
}
move_began=move_ing;
}


3、滚动条

实现思路:
1)滚动条的大小由可见行数决定:滚动条高度=可见行数*每个Item的高度

2)滚动Button的大小由当前最大行数和可见行数决定:滚动Button的大小=可见行/最大行 * 滚动条高度

3)滚动条的位置由GridView当前位置和GridView最大可以上升的位置、滚动Button大小和滚动条大小决定

可以这样理解:

GridView上升高度/最大可以上升高度 = Button下降高度/Button最大可以下降高度

其中,GridView的上升高度和最大上升高度可以直接获取,Button的最大下降高度= 滚动条大小-Button大小

因此,可以求出Button的下降高度。也就可以确定Button的位置


4、GridView主要用途

GridView可以用来做背包视图,或者一个简单的listView(需要设置列数为1)


最后,附上源码:注意要把那两个图片放到resource文件夹里面哦


源码下载:带滚动的表格GridView

Cocos2d-x 3.2编写常用UI组件 《Cocos2d-x 3.2编写常用UI组件 带滚动的表格GridView的更多相关文章

  1. Html5原创俄罗斯方块(基于canvas)

    这篇文章主要介绍了Html5原创俄罗斯方块(基于canvas)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. swift 数据类型转换 string 转换为 int, int转换为string 等等 string转换为nsmutablestring

    bytheway:刚接触swift不就,学到的东西比较浅~~,但是有问题可以在评论里说说,我每天上,一起成长~~早晚小牛长成大牛,~more牛~~~牛的立方~~gogo

  3. 【swift_1】swift基本语法及事例Demo

    语法类的文档网上比较多,我这里参考:Swift基本语法事例Demo:链接:http://pan.baidu.com/s/1jGCINCq密码:5mdk语法须知2个不需要不需要编写main函数:全局作用域中的代码会被自动当做程序的入口点(从上往下执行)不需要在每一条语句后面加上分号letradius=10你喜欢的话,也可以加上letradius=10;有一种情况必须加分号:同一行代码上有多条语句时1

  4. 数组的enumerate(swift)

    数组的enumerateby伍雪颖letarr:Array=[1,2,216)">3,216)">4,216)">5]varresult=0forinenumerate{result+=num}println

  5. swift语言的学习笔记十二(初始化方法)

    所以Swift有了超级严格的初始化方法。与designated初始化方法对应的是在init前加上convenience关键字的初始化方法。所有的convenience初始化方法都必须调用同一个类中的designated初始化完成设置,另外convenience的初始化方法是不能被子类重写或从子类中以super的方式被调用的。这样的一个最大的好处是可以保证依赖于某个designated初始化方法的convenience一直可以被使用。这在要求子类不直接使用父类中的convenience初始化方法时会非常有帮

  6. Swift 柯里化(currying)和反柯里化(uncurrying)

    //DemoofcurryingfuncaddTwoNums(a:Int)(num:Int)->Int{returna+num}letaddToFour=addTwoNums(4)letresult=addToFour(num:6)print("result:\(result)")funcgreaterThan(comparor:Int)(input:Int)->Bool{returninput>

  7. 从零学习Swift&lt;2&gt;

    ,可以强行解包注意:必须要确保解包后的值不是nil,否则会报错常见错误unexpectedlyfoundnilwhileunwrappinganOptionalvalue翻译在[解包]一个可选值时发现nil??运算符可以用于判断变量/常量的数值是否是nil,如果是则使用后面的值替代在使用Swift开发时,??

  8. 挺好的一篇总结文(等有空时看看)

    最近几天的感受是,Swift并不像我上一篇表达自己初步看法的文章里所说的那样,相对于objc来说有更好的学习曲线。另外一种类型是复合类型,包括函数和多元组。它们在使用的时候不会被命名,而是由Swift内部自己定义。在Swift的世界中,一切看得到的东西,都一定属于某一种类型。这也正式Swift的类型的一种很常见的组织方式。而当我们检查到Array的时候,发生了一点神奇的事情。这里的原因其实在Apple的官方文档中有一些说明。

  9. Swift 338. Counting Bits

    Givenanonnegativeintegernumbernum.Foreverynumbersiintherange0≤i≤numcalculatethenumberof1'sintheirbinaryrepresentationandreturnthemasanarray.Example:Fornum=5youshouldreturn[0,1,2,2].题意:给定num,计算从0到num中的

  10. 早期Swift中Cocos2D初始化代码的重构

    但是遗憾的是Swift2.2中还是不支持Type的class属性关键字,只能用static,我们期待Swift3的改进吧!

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部