cocos2dx——cocostudio界面的使用详解

10 篇文章 0 订阅
4 篇文章 0 订阅

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, sender, 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个按钮的情况吧(不知后面是否会在事件里加入按钮的参数),多个按钮的话给模板里的该按钮加就行。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值