【Cocos2dx工具】Cocostudio界面编辑器三
更新:HHH   时间:2023-1-7


Cocos2dx工具之Cocostudio界面编辑器】

写在前面——

如果转载请注明出处,谢谢大家支持

同步更新51CTO博客

——Forward

我的微博——龙颜硕

        Hello,大家好,Forward新一期的博客有和大家见面了。接着上一期《【Cocos2dx工具——Cocostudio界面编辑器】二》末尾所提出的问题,我们往下说——

        1CocoGUILIB的结构是什么样子呢?

        2、从文件解析到控件创建,CocoGUILIB是如何实现的呢?

        3、有关Touch事件又是如何接收与处理呢?

        4CocoGUILIB是如何工作的呢?


好的,带着以上几个问题,我们正式开始学习CocoGUILIB库。这里我们依然使用《二》中用到的那个例子UIEditorDemo来说明。

按照Forward学习的习惯——在学习一样新知识时,最好对整体先有一个宏观哪怕浅显的认识也好,这里Forward根据自己里的理解,绘制了一个类图(个人UML不是特别熟悉,有使用不恰当的符号,大家多多指正)

1

首先需要说明的是,Forward在完成这篇博客的时候,使用额CocoGUILIB库版本号是0.1.3


2

如上图所示,CocoGUILIB库的核心主要是一个UISystem类,它主要依靠内部的InputLayer类来接受Touch事件(具体我们后面会详细描述)、CocoRootWidget(通过这个Widget来保存所有包括在它之上的控件UI),其余两个(UISceneUIManager是协助完成Widget控件的控制和Touch事件的分发的,具体的话我们可以看源代码),初次以外,UISystem外部还依赖与一个CSJsonDictionary类,这个类是对Json协议的一个封装,使用起来更加方便罢了(Forward曾经在一篇博客《Protocol buffer介绍》中有提到过Json协议,后期Forward会根据Json的相关知识完成一篇博客)。

3

再看上面类图,CocoRootWidget最终继承自CocoWidget,这就是一个逻辑概念上的一个控件,具体的控件当前版本支持CocoButtonCocoCheckBoxCocoImageViewCocoLabelCocoLabelAtlasCocoLoadingBarCocoPanelCocoScrollViewCocoSliderCocoTextAreaCocoTextButtonCocoTextField等,相信后续会有更多更好用的控件出炉^_^

了解了逻辑控件之后呢,我们再往下看,可以看到有一个CCRenderNode模块,很容易想到,这一模块就是具体的控件加载所需的一个模块,包括CClipAbleLayerColorCClipAbleSpriteCLabelAtlasCPrimitivesNodeCTextFieldGUINodeRGBA等,追踪源代码,我们可以发现,这几个自定义类又都分别继承自Cocos2dx的一些CCNode或其子类,这样就很清楚了,其实一个完成的UI在加载的时候其实都是一层层的CCNode堆叠而成的。

经过以上的分析,相信大家已经对CocoGUILIB库有了一个整体上的认识,下面我们接着博客开题提到的问题继续学习——


大家是否还记得,在《Cocos2dx工具之Cocostudio界面编辑器一》中我们就提到通过界面编辑器编辑之后我们会得到一个Json格式的UI文件。今天我们通过上面的学习,相信不用我再赘述,大家脑海中已经有了一个下面这样一个流程图——

4

流程图可能并不美观,但它足以说明问题了,哈哈。


好了知道了上面这些以后,或许我们应该关注一下对于UI来说最为重要的一个特性就是交互性的实现,当然UI来说交互一般都是通过点击、拖拽等事件来完成。

对于UI交互,我们的CocoGUILIB是依赖一个InputLayer层来实现的,上面已经提到。

virtualboolccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);

virtualvoidccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);

virtualvoidccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);

virtualvoidccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);

正如我们所说的,InputLayer中重写了这几种Touch事件,那么他们的注册在哪里呢?我们打开UISystem.cpp可以在resetSystem接口中看到其注册如下:

this->m_pInputLayer =InputLayer::createWithUISystem(this);

this->m_pInputLayer->retain();

this->m_pInputLayer->setTouchEnabled(true);

      cocos2d::CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this->m_pInputLayer, nPriority, true);

这样,当InputLayer这个层收到Touch事件之后,他就将根据事件的不同调用UISystem几种不同接口:

bool InputLayer::ccTouchBegan(cocos2d::CCTouch*pTouch, cocos2d::CCEvent *pEvent)

   {

returnthis->m_pUISystem->onTouchPressed(pTouch);  

   }


void InputLayer::ccTouchMoved(cocos2d::CCTouch*pTouch, cocos2d::CCEvent *pEvent)

   {

this->m_pUISystem->onTouchMoved(pTouch);

   }


void InputLayer::ccTouchEnded(cocos2d::CCTouch*pTouch, cocos2d::CCEvent *pEvent)

   {

this->m_pUISystem->onTouchReleased(pTouch);

   }


void InputLayer::ccTouchCancelled(cocos2d::CCTouch*pTouch, cocos2d::CCEvent *pEvent)

   {

this->m_pUISystem->onTouchCanceled(pTouch);

   }

        UISystem在收到不同的消息时再通过InputManager将这个Touch事件传递给这个UISystem中的每一个需要获取该消息的Widget控件。这就是UISystemTouch事件处理的全过程了。

哈哈,不早了,明天还得上班,Forward的本次博客就先写到这里了,拜拜~~


返回开发技术教程...