引擎: cocos2d-js 3.0
这只是一个简单的,循环的版本,后期再给大家呈现实时滑动的版本。
为了方便对齐坐标,所以这个控件结合了cocos studio1.6的编辑器。
编辑器的编辑效果如下:
ClipPanel是一个大小为选择区域的裁剪Panel(设置裁剪)。
Image_BackGround是左右黑色渐变的背景,位于图片上层。
Image_0到Image_3是4个基本的移动对象。由于要实现切换的效果,最少需要用到的精灵个数为4个。所以为了最优的性能,我们用4个精灵来模拟。
Label_Tile是上方的标题
Btn_Right和Btn_Left是左右的按钮,用来切换
Btn_Panel是大小同精灵一样的Panel,用来点击选择进入哪一个场景。(切换到相应的地方后,总得要确定选择吧)
由于最初我们设计是循环的控件,因此默认正中间的是第一个对象,左边是列表的最后一个对象,向左边数第二个是倒数第二个对象,右边是第二个对象。如下图:
这里的Image_2在游戏中是看不见的,被裁剪了。
提问:也有朋友觉得这样做不觉得麻烦吗,我列表中有多少个就创建多少个,这样管理不更直接,更简单吗。
我答:如果说需要切换的列表有100个,甚至100个以上的对象怎么破?
接着,我们知道了编辑器的操作后,再来看实际的带代码:
- var SwitchTable = cc.Layer.extend({
-
- _curIndex:null,_list:null,_spriteList:null,_originPosition:null,_root:null,_objList:null,_isCanMove:true,// 设定操作间隔
-
- ctor: function(json){
- this._super();
- this._curIndex = 0;
- this._list = [];
- this._originPosition = [];
- this._root = ccs.uiReader.widgetFromJsonFile(json);
- this.addChild(this._root);
- for(var i = 0; i < 4; i++){
- var sprite = ccui.helper.seekWidgetByName(this._root,"Image_"+i);
- this._originPosition.push(sprite.getPosition());
- this._list.push(sprite);
- }
- // ini button
- var rightBtn = ccui.helper.seekWidgetByName(this._root,"Btn_Right");
- rightBtn.addTouchEventListener(this._touchEvent,this);
- var leftBtn = ccui.helper.seekWidgetByName(this._root,"Btn_Left");
- leftBtn.addTouchEventListener(this._touchEvent,this);
- var panelBtn = ccui.helper.seekWidgetByName(this._root,"Btn_Panel");
- panelBtn.addTouchEventListener(this._clicked,this);
- this._labTitle = ccui.helper.seekWidgetByName(this._root,"Label_Title");
- },initWithObjList: function (objList) {
- this._objList = objList;
- // 清空目前的Sprite,切换其他ObjList
- this._clear();
- // 根据列表放置sprite
- var length = objList.length;
- for( var i = 0; i < 2; i++){ // 头两个
- if(objList[i]){
- this._list[i].loadTexture(objList[i].imgName);
- }
- }
- var listLength = this._list.length;
- for( var i = length - 1; i >= length - 2; i--){ // 尾两个
- if(objList[i]){
- this._list[listLength-1].loadTexture(objList[i].imgName);
- listLength = listLength - 1;
- }
- }
- // 个数处理,如果为1,2,3时
- if(length == 1){
- this._list[1].setVisible(false);
- this._list[2].setVisible(false);
- this._list[3].setVisible(false);
- }else if( length == 2){
- this._list[2].setVisible(false);
- this._list[3].setVisible(false);
- }else if( length == 3){
- this._list[2].setVisible(false);
- }
-
- this._curIndex = 0;
- this._labTitle.setString(this._objList[this._curIndex].titleName);
- },_scroll: function(direction){
- if(!this._isCanMove) return;
- var length = this._objList.length;
- if(length <= 1 ) return; // 不足长度是无法移动
-
- if(direction == 0){
- if(length == 2 && this._curIndex == 1) return;
- if(length == 3 && this._curIndex == 1) return;
- this._curIndex = (this._curIndex + 1) >= length ? 0 : this._curIndex + 1;
- var index = this._curIndex + 1 >= this._objList.length ? 0 : this._curIndex + 1;
- if(this._objList[index]){
- this._list[2].loadTexture(this._objList[index].imgName);
- }
- this._moveToLeft();
-
- }else{
- if(length == 2 && this._curIndex == 0) return;
- if(length == 3 && this._curIndex == 2) return;
- this._curIndex = (this._curIndex - 1) < 0 ? length - 1 : this._curIndex - 1;
- this._moveToRight();
- }
-
- this._isCanMove = false;
- this.runAction(cc.sequence(cc.delayTime(0.3),cc.callFunc(function(){
- this._isCanMove = true;
- if(direction == 0){
-
- }else{
- var index = this._curIndex - 2 < 0 ? this._objList.length + (this._curIndex - 2) : this._curIndex - 2;
- if(this._objList[index]){
- this._list[2].loadTexture(this._objList[index].imgName);
- }
- }
-
-
- },this)));
-
- this._labTitle.setString(this._objList[this._curIndex].titleName);
- },_moveToRight: function(){
- var time = 0.3;
-
- this._list[0].runAction(cc.spawn(cc.moveTo(time,this._originPosition[1]),cc.scaleTo(time,0.8)));
- this._list[1].runAction(cc.moveBy(time,cc.p(this._list[2].getContentSize().width + 5,0)));
- this._list[2].setPosition(this._originPosition[2]);
- this._list[2].runAction(cc.moveTo(time,this._originPosition[3]));
- this._list[3].runAction(cc.spawn(cc.moveTo(time,this._originPosition[0]),1)));
-
- var tempSp = this._list[0];
- this._list[0] = this._list[3];
- this._list[3] = this._list[2];
- this._list[2] = this._list[1];
- this._list[1] = tempSp;
-
- },_moveToLeft: function(){
- var time = 0.3;
-
- this._list[0].runAction(cc.spawn(cc.moveTo(time,this._originPosition[3]),0.8)));
- this._list[3].runAction(cc.moveBy(time,cc.p(-this._list[2].getContentSize().width + 5,0)));
- this._list[2].setPosition(cc.p(this._originPosition[1].x + this._list[2].getContentSize().width,this._originPosition[1].y));
- this._list[2].runAction(cc.moveTo(time,this._originPosition[1]));
- this._list[1].runAction(cc.spawn(cc.moveTo(time,1)));
-
- var tempSp = this._list[0];
- this._list[0] = this._list[1];
- this._list[1] = this._list[2];
- this._list[2] = this._list[3];
- this._list[3] = tempSp;
-
- },_clear: function(){
- //this._list[2].setVisible(false);
-
- this._curIndex = 0;
- },_touchEvent: function (sender,type) {
- switch (type) {
- case ccui.Widget.TOUCH_ENDED:
- var tag = sender.getTag();
- this._scroll(tag);
- break;
- default:
- break;
- }
- },_clicked: function (sender,type) {
- /*if (type == ccui.Widget.TOUCH_ENDED) { window.open(....); }*/
- }
- });
(1)左右按钮通过tag的设置来区分
(2)由于1~3个个数的时候数量太少,无法支持循环,所有上方判断。
(3)SwitchTable名字是我随便取的^ ^
下周会把一个通用的、跟随手指滑动的控件给大家贴出来。