《Cocos Creator游戏实战》实现下拉框按钮ComboBox控件

实现下拉框按钮ComboBox控件

创建节点

编写脚本


官方目前并没有在Cocos Creator中提供ComboBox控件,不过我们自己完全可以做一个,实现起来并不难。

运行效果如下:

Cocos Creator版本:2.2.0

公众号后台回复"下拉框",获取完整项目源码:

创建节点

1. bg只是一个Sprite节点,用来当做画布背景。

2. 重点是combobox节点。它其实是一个按钮,background子节点为按钮背景,triangle子节点类型同样为Sprite,而label就是按钮上的文本了。

我们将combobox节点上的按钮组件Transition属性设置为None(之后笔者将通过三角形图片的旋转来体现玩家点击操作):

注:关于所有节点的坐标、锚点和大小设置,笔者这里就不再截图,大家可以直接打开项目查看(大家当然也可以根据自己喜好来调整)。

我们给triangle和label节点挂上Widget组件,让他们在按钮上的相对位置固定:

triangle

label

label节点上的Label组件设置如下(默认文本为Cocos Creator,Overflow建议设置成SHRINK):

按钮现在做好了,可以做下拉框了。下拉框我们用ScrollView控件来做,在combobox节点下创建一个dropDown节点:

现将其修改如下:

1. 将原先content节点下的item子节点删掉,换成vLayout节点(垂直布局)。

2. 在vLayout节点下有一个labelBtnItem按钮节点(已将background删掉)。

笔者这里的思路是:下拉框中的每一项内容都是按钮,当玩家点击某个按钮后,combobox下的label节点文本就直接替换为相应按钮上的文本。所有的按钮都放在垂直布局中,方便排版。

查看项目时,大家可以看到笔者将dropDown,view,content和vLayout这几个节点的大小和锚点全部设置成一样的了,大家当然也可以根据自己想法改。笔者设置好后是这个样子:

现在有一个问题:下拉框中的选项怎么添加?

我们自然而然想到将labelBtnItem变为预制,然后在脚本中创建一个包含所有下拉框选项的数组,循环该数组创建各个预制即可。

编写脚本

新建一个ComboBox.js脚本,将其挂到combobox节点上。

我们在properties中添加如下属性:

// ComboBox.js
properties: {
    triangle: cc.Node,          // 下拉按钮右边的小三角形
    comboLabel: cc.Label,       // 下拉按钮上显示的文本
    dropDown: cc.Node,          // 下拉框
    vLayoutNode: cc.Node,       // 垂直布局
    contentNode: cc.Node,       // 滚动视图内容
    itemPrefab: cc.Prefab       // 下拉框选项
},

首先完成"点击出现下拉框"这个功能。在onLoad中新建this.isDropDown布尔类型变量,用于判断当前下拉状态:

// ComboBox.js
onLoad () {
    // 是否已经下拉
    this.isDropDown = false;
}

编写rotateTriangle方法旋转小三角图案:

// ComboBox.js
rotateTriangle () {
    // 旋转小三角形(正值为逆时针,负值为顺时针)
    if (!this.isDropDown) {
        let rotateAction = cc.rotateTo(0.5, 180).easing(cc.easeCubicActionOut());
        this.triangle.runAction(rotateAction);
    }
    else {
        let rotateAction = cc.rotateTo(0.5, -90).easing(cc.easeCubicActionOut());
        this.triangle.runAction(rotateAction);
    }
},

点击前:

点击后:

编写showHideDropDownBox方法来显示与隐藏下拉框:

// ComboBox.js
showHideDropDownBox () {
    // 下拉框显示与隐藏
    if (!this.isDropDown) 
        this.dropDown.active = true;
    else 
        this.dropDown.active = false;
},

注:要先将dropDown节点设置为不可见。

点击前:

点击后:

编写comboboxClicked按钮方法,每当玩家点击了combobox按钮后(记得要绑定该方法),小三角形和下拉框作出相应操作:

// ComboBox.js
comboboxClicked () {
    // 旋转小三角形
    this.rotateTriangle();
    // 下拉框显示与隐藏
    this.showHideDropDownBox();
    // 改变isDropDown值
    if (!this.isDropDown)
        this.isDropDown = true;
    else 
        this.isDropDown = false;
},

记得最后要改变this.isDropDown的值。

现在来添加下拉框中的选项内容。在onLoad中创建选项数组并调用initItems方法:

// ComboBox.js
onLoad () {
    // 是否已经下拉
    this.isDropDown = false;

    // 下拉框选项内容
    this.itemArray = ['Cocos Creator', 'Cocos-2dx', 'Cocos2d-js', 'Cocos2d-Lua', 'Cocos Creator 3D', 'Cocos Service', 'Cocos社区'];
    this.initItems();
},

initItems方法编写如下:

// ComboBox.js
initItems () {
    // 根据数组初始化下拉框中的各个选项内容
    let totalHeight = 0;
    for (let i=0; i<this.itemArray.length; i++) {
        let item = cc.instantiate(this.itemPrefab);
        item.children[0].getComponent(cc.Label).string = this.itemArray[i];
        item.getComponent('Item').initComboBox(this);
        this.vLayoutNode.addChild(item);
        totalHeight += item.height;
    }

    // 设置content高度
    if (totalHeight > this.contentNode.height) 
        this.contentNode.height = totalHeight;
}

根据数组元素创建相应的预制,各个预制之后都被添加到了vLayoutNode中。

注:我们要根据所有预制的长度总和来调整content节点的长度,否则选项内容过多的话,在滚动视图上不会显示完整的。

大家应该注意到了item.getComponent('Item').initComboBox(this);这行代码,也就是说每个预制上其实挂有一个Item.js脚本,在该脚本中我们将下拉按钮上的文本替换成了被点击按钮上的文本:

// Item.js
cc.Class({
    extends: cc.Component,

    properties: {
    },

    // LIFE-CYCLE CALLBACKS:
    // onLoad () {},

    initComboBox (cb) {
        this.cb = cb;
    },

    itemBtn (event) {
        // 子项点击后改变下拉按钮上的文本
        this.cb.comboLabel.string = event.target.children[0].getComponent(cc.Label).string;
        // 选择后改变小三角和下拉框显示
        this.cb.comboboxClicked();
    },

    // update (dt) {},
});

好的,教程到这就结束了,希望大家有所收获!

欢迎关注我的微信公众号,发现更多有趣内容:

发布了83 篇原创文章 · 获赞 157 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/La_vie_est_belle/article/details/103689324