cocos2dx——cocostudio界面的使用详解

前端之家收集整理的这篇文章主要介绍了cocos2dx——cocostudio界面的使用详解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1.我用最新的2.3的cocostudio摆了个简单的界面:


继承关系(名字比较乱没改):


2.在cocos2dx lua程序中使用

【加载界面】

用cocostudio导出为csb文件,放到资源目录去,添加该ui代码如下:

-- load csb
local node = cc.CSLoader:createNode('Test.csb')
layer:addChild(node)

【按钮Button】

cocos3.x的版本比较强调用事件来传递消息,减少模块间的耦合。这里gui的处理也基本时给要处理的控件添加事件侦听。

-- btn
local btn = node:getChildByName('btn_ok')
btn:addTouchEventListener(function(sender,state)
    -- 2
    if state == ccui.TouchEventType.ended then
        print('on btn ok')
    end    
end)

【进度条LoadingBar和复选框CheckBox
-- loading bar
local loading = node:getChildByName('LoadingBar_1')

-- checkBox
local chk = node:getChildByName('CheckBox_1')
chk:addEventListener(function (sender,type)
    -- 0
    if type == ccui.CheckBoxEventType.selected then
        -- sel
        print('sel')
        loading:setPercent(50)
    else
        -- unsel
        print('unsel')
        loading:setPercent(0)
    end
end)

【列表控件ListView】

容器有好几个,ScrollView和PageView都比较容易,这里说下ListView。

ListView可以设置列表项的模型,设置了后可以轻松的克隆多个。他的用处就是美术可以在编辑器里把模板编辑好,程序拿来克隆就行了。如果有多种类型,美术就多摆几个,程序搭框架的时候封装一层设置模型的逻辑来选择用哪个模板,这样也可以实现不同的列表项。具体后面有空可以写些例子。

下面设置模板并创建多个:

-- set item model
local item = list:getChildByName('Image_item')
list:setItemModel(item)
list:removeAllChildren()

for i = 1,10 do
    list:pushBackDefaultItem()
end
我这里的模板是在编辑器里放在listview下的,设置完就移除了(注意移除要用listview来remove,不要removeFromParent)。此时的运行效果如下:


下面我们想要相应按钮按下:

list:addEventListener(function (sender,type)
    -- 0
    if type == ccui.ListViewEventType.ONSELECTEDITEM_START then
        -- sel
        print("select child index = ",sender:getCurSelectedIndex())        
        loading:setPercent(50)
    else
        -- unsel
        print('unsel')
        loading:setPercent(0)
    end
end)
当按钮刚按下(其实是其touchBegan的时候)的时候是start事件,抬起的时候(即touchEnded)是end事件。这时你会问为何添加的是list的事件,却能在按钮按下的时候收到消息。这是因为他们的基类Widget和ListView做了一些事情。

Widget会在touchBegan之类的触摸处理里向父亲传递该事件:

bool Widget::onTouchBegan(Touch *touch,Event *unusedEvent)
{
    _hitted = false;
    if (isVisible() && isEnabled() && isAncestorsEnabled() && isAncestorsVisible(this) )
    {
        _touchBeganPosition = touch->getLocation();
        if(hitTest(_touchBeganPosition) && isClippingParentContainsPoint(_touchBeganPosition))
        {
            _hitted = true;
        }
    }
    if (!_hitted)
    {
        return false;
    }
    setHighlighted(true);

    /*
     * Propagate touch events to its parents
     */
    if (_propagateTouchEvents)
    {
        this->propagateTouchEvent(TouchEventType::BEGAN,this,touch);
    }

    pushDownEvent();
    return true;
}

void Widget::interceptTouchEvent(cocos2d::ui::Widget::TouchEventType event,cocos2d::ui::Widget *sender,Touch *touch)
{
    Widget* widgetParent = getWidgetParent();
    if (widgetParent)
    {
        widgetParent->interceptTouchEvent(event,sender,touch);
    }

}
这样当一个widget被触摸的时候,他的祖先们都会(有机会)得知他的某个后辈被触摸了。所以这里按钮按下时,listview能收到该事件并处理:
void ListView::interceptTouchEvent(TouchEventType event,Widget *sender,Touch* touch)
{
    ScrollView::interceptTouchEvent(event,touch);
    if (event != TouchEventType::MOVED)
    {
        Widget* parent = sender;
        while (parent)
        {
            if (parent && parent->getParent() == _innerContainer)
            {
                _curSelectedIndex = getIndex(parent);
                break;
            }
            parent = dynamic_cast<Widget*>(parent->getParent());
        }
        if (sender->isHighlighted()) {
            selectedItemEvent(event);
        }
    }
}

void ListView::selectedItemEvent(TouchEventType event)
{
    this->retain();
    switch (event)
    {
        case TouchEventType::BEGAN:
        {
            if (_listViewEventListener && _listViewEventSelector)
            {
                (_listViewEventListener->*_listViewEventSelector)(this,LISTVIEW_ONSELECTEDITEM_START);
            }
            if (_eventCallback) {
                _eventCallback(this,EventType::ON_SELECTED_ITEM_START);
            }
            if (_ccEventCallback)
            {
                _ccEventCallback(this,static_cast<int>(EventType::ON_SELECTED_ITEM_START));
            }
        }
        break;
        default:
        {
            if (_listViewEventListener && _listViewEventSelector)
            {
                (_listViewEventListener->*_listViewEventSelector)(this,LISTVIEW_ONSELECTEDITEM_END);
            }
            if (_eventCallback) {
                _eventCallback(this,EventType::ON_SELECTED_ITEM_END);
            }
            if (_ccEventCallback)
            {
                _ccEventCallback(this,static_cast<int>(EventType::ON_SELECTED_ITEM_END));
            }
        }
        break;
    }
    this->release();
}
这样的结果就是只要某个item下的某个按钮被触摸了listview就会收到,所以问题也来了,如果有多个按钮怎么办?上面listview的事件参数只有this(是listview指针)和事件类型,没法知道是哪个按钮被按下了。通过curSel只能得知是哪个item被按下了,需要区分是item下的哪个按钮被按下了,则最好给按钮添加事件处理。

你担心按钮多懒得添加,那么我们就使用模板呗,给模板加事件处理,通过模板克隆的列表项也会有该处理的。将下面这段lua代码添加到设置模板之前:

-- set item callback: we can just add event to model,and diff from curSel
local item0 = list:getItem(0)
local btn_0 = item0:getChildByName('Button_2')
btn_0:addTouchEventListener(function(sender,state)
    if state == 2 then
        print('on btn test 0')
    end    
end)
这样就能给每个列表项的按钮添加事件并响应了。所以listview的触摸事件只能用于1个按钮的情况吧(不知后面是否会在事件里加入按钮的参数),多个按钮的话给模板里的该按钮加就行。

猜你在找的Cocos2d-x相关文章