Cocos2d-x 之简单 UI 及事件

写在前面

Cocos2d经过几个版本的迭代,UI系统比较多,也比较乱,对于我们初学者来说,不必做到大而全,只需要掌握一种比较常用的就行。这篇文章主要介绍cocos studio中使用的UI系统。

UI的根:Widget

Widget是整个UI系统的根类,它定义了UI控件共有的一些属性和方法,还有事件。

void UITest::WidgetTest(Widget *pWidget)
{
    pWidget->setColor(Color3B(0, 128, 0));
    pWidget->setBright(true);
    pWidget->setEnabled(true);
    pWidget->setFlippedX(true);
    pWidget->setFlippedY(false);
    pWidget->setBrightStyle(Widget::BrightStyle::HIGHLIGHT);
    pWidget->setOpacity(255);
    pWidget->setName("widget");
    pWidget->setFocused(true);
    pWidget->setVisible(true);
    pWidget->setZOrder(100);
    pWidget->setTag(1);
}

Zorder表示控件的显示深度,Zorder越大,控件越显示在顶层。3.0 之后 zorder 改名为 lcoalzorder,另外 还有一个 globalzorder,如果要调整层级关系的两个控件隶属于同一个父结点,则使用 localzorder 即可,否则要使用 globalzorder。
Widget 可以监听三个事件,触摸事件 TouchEventListener,点击事件 ClickEventListener 和 cocostudio事件 CCSEventListener

pWidget->addTouchEventListener(CC_CALLBACK_2(UITest::OnWidgetTouch, this));
pWidget->addClickEventListener(CC_CALLBACK_1(UITest::OnWidgetClick, this));
pWidget->addCCSEventListener(CC_CALLBACK_2(UITest::OnWidgetCCSEvent, this));
void UITest::OnWidgetTouch(Ref *pRef, Widget::TouchEventType type)
{
    switch (type)
    {
    case Widget::TouchEventType::BEGAN:
        log("touch begin");
        break;
    case Widget::TouchEventType::ENDED:
        log("touch end");
        break;
    case Widget::TouchEventType::MOVED:
        log("touch move");
    case Widget::TouchEventType::CANCELED:
        log("touch cancel");
        break;
    }
}

void UITest::OnWidgetClick(Ref *pRef)
{
    log("click");
}

void UITest::OnWidgetCCSEvent(Ref *pRef, int id)
{
    log("%d", id);
}

按钮:Button

Widget *UITest::TestButton()
{
    m_pButton = Button::create();
    m_pButton->loadTextureNormal("res/Default/Button_Normal.png");
    m_pButton->loadTextureDisabled("res/Default/Button_Disable.png");
    m_pButton->loadTexturePressed("res/Default/Button_Press.png");
    m_pButton->setTitleText("StartGame");
    m_pButton->setTitleColor(Color3B(128, 0, 0));
    WidgetTest(m_pButton);
    return m_pButton;
}

按钮的主要事件是是触摸或者点击,这两个事件直接继承Widget,按钮没有特有的事件。

静态文本:Text、TextAtlas、TextBMFont

在旧版本中,使用文本可以Label,LabelTTF,LabelAtlas和LabelBMFont,新版本这几个类还保留,但它们不属于UI系统,新版本的引擎整合了几个新的类,它们属于UI系统的一部分,也是继承Widget,拥有Widget类的属性和事件方法。

  • Text相当于Label和LabelTTF,因此Text是可以指定ttf字体的,并且可以有描边和阴影效果。
  • TextAtlas相当于LabelAtlas,使用这种文本必须指定一个图片文件,使用的字符都必须在这张图片上,使用起来不是很方便,并不好用。
  • TextBMFont相当于LabelBMFont,使用这种文本必须指定一个图片文件和一个同名的fnt文件,使用成本更加的高。
  • TextAltas和TextBMFont的使用场景是一些特殊的要求,它们的原理其实只是用图片来显示文本,所以没特殊要求的情况我们用Text就足以,且Text也可以指定ttf字体,完全可以满足一般的要求。
Widget *UITest::TestText()
{
    m_pText = Text::create("hello", "arial", 38);
    WidgetTest(m_pText);
    m_pText->setZOrder(20);
    m_pText->setFontName("fonts/Marker Felt.ttf");
    m_pText->setFontSize(36);
    m_pText->setTextColor(Color4B(0, 255, 0, 255));
    m_pText->setTextHorizontalAlignment(TextHAlignment::CENTER);
    m_pText->setTextVerticalAlignment(TextVAlignment::CENTER);
    return m_pText;
}

Widget *UITest::TestTextAtlas()
{
    m_pTextAtlas = TextAtlas::create("1", "fonts/labelatlas.png", 32, 32, "0");
    m_pTextAtlas->setString("123456");
    WidgetTest(m_pTextAtlas);
    return m_pTextAtlas;
}

Widget *UITest::TestTextBMF()
{
    m_pTextBMF = TextBMFont::create("hello", "fonts/bitmapFontTest2.fnt");
    WidgetTest(m_pTextBMF);
    return m_pTextBMF;
}

文本也同样没有自己独有的事件。

输入文本:TextField

使用 TextField 可以输入普通文本和密码。

Widget *UITest::TestTextField()
{
    m_pTextField = TextField::create("please input", "arial", 30);
    m_pTextField->setDetachWithIME(false);
    m_pTextField->setAttachWithIME(false);
    m_pTextField->setPasswordEnabled(true);
    m_pTextField->setPasswordStyleText("*");
    WidgetTest(m_pTextField);
    return m_pTextField;
}

TexField有自己独有的事件

m_pTextField->addEventListener(CC_CALLBACK_2(UITest::OnTextFieldTrigger, this));
void UITest::OnTextFieldTrigger(Ref *pRef, TextField::EventType type)
{
    switch (type)
    {
    case TextField::EventType::ATTACH_WITH_IME:
        log("attach ime");
        break;
    case TextField::EventType::DETACH_WITH_IME:
        log("detach ime");
        break;
    case TextField::EventType::INSERT_TEXT:
        log("insert word");
        break;
    case TextField::EventType::DELETE_BACKWARD:
        log("delete word");
        break;
    }
}

复选框:CheckBox

Widget *UITest::TestCheckBox()
{
    m_pCheck = CheckBox::create();
    m_pCheck->loadTextureBackGround("res/Default/CheckBox_Normal.png");
    m_pCheck->loadTextureBackGroundDisabled("res/Default/CheckBox_Disable.png");
    m_pCheck->loadTextureBackGroundSelected("res/Default/CheckBox_Press.png");
    m_pCheck->loadTextureFrontCross("res/Default/CheckBoxNode_Normal.png");
    m_pCheck->loadTextureFrontCrossDisabled("res/Default/CheckBoxNode_Disable.png");
    m_pCheck->setSelected(true);
    WidgetTest(m_pCheck);
    m_pCheck->setEnabled(false);
    return m_pCheck;
}

CheckBox 有选中和取消选中事件

m_pCheck->addEventListener(CC_CALLBACK_2(UITest::OnCheckBoxTrigger, this));
void UITest::OnCheckBoxTrigger(Ref *pRef, CheckBox::EventType type)
{
    switch (type)
    {
    case CheckBox::EventType::SELECTED:
        log("selected");
        break;
    case CheckBox::EventType::UNSELECTED:
        log("unselected");
        break;
    }
}

滚动条:Slider

Widget *UITest::TestSlider()
{
    m_pSlider = Slider::create();
    m_pSlider->loadBarTexture("sliderTrack.png");
    m_pSlider->loadProgressBarTexture("sliderProgress.png");
    m_pSlider->loadSlidBallTextureNormal("res/Default/SliderNode_Normal.png");
    m_pSlider->loadSlidBallTexturePressed("res/Default/SliderNode_Press.png");
    m_pSlider->loadSlidBallTextureDisabled("res/Default/SliderNode_Disable.png");
    WidgetTest(m_pSlider);
    return m_pSlider;
}

Slider事件

m_pSlider->addEventListener(CC_CALLBACK_2(UITest::OnSliderTrigger, this));
void UITest::OnSliderTrigger(Ref *pRef, Slider::EventType type)
{
    switch (type)
    {
    case cocos2d::ui::Slider::EventType::ON_PERCENTAGE_CHANGED:
        log("precent:%d%%", m_pSlider->getPercent());
        break;
    case cocos2d::ui::Slider::EventType::ON_SLIDEBALL_DOWN:
        log("slider down");
        break;
    case cocos2d::ui::Slider::EventType::ON_SLIDEBALL_UP:
        log("slider up");
        break;
    case cocos2d::ui::Slider::EventType::ON_SLIDEBALL_CANCEL:
        log("slider cancel");
        break;
    default:
        break;
    }
}

进度条:LoadingBar

Widget *UITest::TestLoadingBar()
{
    m_pBar = LoadingBar::create();
    m_pBar->loadTexture("res/Default/LoadingBarFile.png");
    m_pBar->setPercent(50);
    WidgetTest(m_pBar);
    return m_pBar;
}

进度条没有自己独有的事件,但它通常需要一个计时器事件或其它事件来设置它的值。

事件

除了 UI 事件外,cocos2d-x 中还有下面几种事件

  • EventListenerAcceleration
  • EventListenerCustom
  • EventListenerFocus
  • EventListenerKeyboard
  • EventListenerMouse
  • EventListenerPhysicsContact
  • EventListenerPhysicsContactWithBodies
  • EventListenerPhysicsContactWithGroup
  • EventListenerPhysicsContactWithShapes
  • EventListenerTouch
  • EventListenerTouchAllAtOnce
  • EventListenerTouchOneByOne
  • EventListenerController

在 c++ 中有两种方式添加事件,回调函数或者闭包

-- 回调函数
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(UIFocusTest::onTouchedBeginTick, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
bool UIFocusTest::onTouchedBeginTick(Touch *t, Event *e)
{
    log("touch");
    return false;
}

-- 闭包
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [](Touch *t, Event *e) {
    log("touch");
    return false;
};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

在 lua 中也一样,只是 lua 中的闭包更加简单,不需要函数绑定

local function onTouchBegan(touch, event)
    return true
end

local function onTouchMoved(touch, event)
end

local function onTouchEnded(touch, event)
end

self._listener = cc.EventListenerTouchOneByOne:create()
self._listener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN)
self._listener:registerScriptHandler(onTouchMoved, cc.Handler.EVENT_TOUCH_MOVED)
self._listener:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED)
cc.Director:getInstance():getEventDispatcher():addEventListenerWithSceneGraphPriority(self._listener, self._menu_btn)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值