您好,登錄后才能下訂單哦!
寫在前面——
如果轉載請注明出處,謝謝大家支持
同步更新51CTO博客
——Forward
我的微博——龍顏碩
Hello,大家好,Forward新一期的博客有和大家見面了。接著上一期《【Cocos2dx工具——Cocostudio界面編輯器】二》末尾所提出的問題,我們往下說——
1、CocoGUILIB的結構是什么樣子呢?
2、從文件解析到控件創建,CocoGUILIB是如何實現的呢?
3、有關Touch事件又是如何接收與處理呢?
4、CocoGUILIB是如何工作的呢?
好的,帶著以上幾個問題,我們正式開始學習CocoGUILIB庫。這里我們依然使用《二》中用到的那個例子UIEditorDemo來說明。
按照Forward學習的習慣——在學習一樣新知識時,最好對整體先有一個宏觀哪怕淺顯的認識也好,這里Forward根據自己里的理解,繪制了一個類圖(個人UML不是特別熟悉,有使用不恰當的符號,大家多多指正)
圖 1
首先需要說明的是,Forward在完成這篇博客的時候,使用額CocoGUILIB庫版本號是0.1.3。
圖 2
如上圖所示,CocoGUILIB庫的核心主要是一個UISystem類,它主要依靠內部的InputLayer類來接受Touch事件(具體我們后面會詳細描述)、CocoRootWidget(通過這個Widget來保存所有包括在它之上的控件UI),其余兩個(UIScene和UIManager是協助完成Widget控件的控制和Touch事件的分發的,具體的話我們可以看源代碼),初次以外,UISystem外部還依賴與一個CSJsonDictionary類,這個類是對Json協議的一個封裝,使用起來更加方便罷了(Forward曾經在一篇博客《Protocol buffer介紹》中有提到過Json協議,后期Forward會根據Json的相關知識完成一篇博客)。
圖 3
再看上面類圖,CocoRootWidget最終繼承自CocoWidget,這就是一個邏輯概念上的一個控件,具體的控件當前版本支持CocoButton、CocoCheckBox、CocoImageView、CocoLabel、CocoLabelAtlas、CocoLoadingBar、CocoPanel、CocoScrollView、CocoSlider、CocoTextArea、CocoTextButton、CocoTextField等,相信后續會有更多更好用的控件出爐^_^。
了解了邏輯控件之后呢,我們再往下看,可以看到有一個CCRenderNode模塊,很容易想到,這一模塊就是具體的控件加載所需的一個模塊,包括CClipAbleLayerColor、CClipAbleSprite、CLabelAtlas、CPrimitivesNode、CTextField、GUINodeRGBA等,追蹤源代碼,我們可以發現,這幾個自定義類又都分別繼承自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控件。這就是UISystem的Touch事件處理的全過程了。
哈哈,不早了,明天還得上班,Forward的本次博客就先寫到這里了,拜拜~~
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。