溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

【cocos2d-x從c++到j(luò)s】22:使用非侵入方式擴展UI系統(tǒng)接口的舉例

發(fā)布時間:2020-07-28 07:43:30 來源:網(wǎng)絡(luò) 閱讀:2374 作者:老G 欄目:游戲開發(fā)

如何較好的運用腳本語言,使用他的動態(tài)性是關(guān)鍵。使用動態(tài)性來擴展代碼,可以保證非侵入方式。這種方式,把原先的引擎代碼和當(dāng)前自己的二次開發(fā)代碼隔離開了,便于后續(xù)的升級維護。而且,又不像繼承那么重量級。


下面就如何用動態(tài)添加的擴展方式,使用非侵入來完善和增強CocoStudio的UI功能,做一舉例:


零、入口函數(shù)


一開始,我們需要加載ui到游戲中,然后我們訪問這個ui,在上面執(zhí)行一系列操作,把結(jié)果對象返回出來。這個代碼的主干就是這個樣子。


var loadUI = function(filepath,owner){
    ui = ccs.GUIReader.getInstance().widgetFromJsonFile(filepath)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
    //一系列操作
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
    return ui;
}



在每次加載控件的時候,要使用這個額外擴展的函數(shù),而不是那個引擎里的自帶函數(shù)。這樣在ui加載完成之后,里面所有的東西都已經(jīng)自動處理好了,直接拿來用就行了。




一、改進子控件訪問方式


getChildByName 和 getChildById實在是很羅嗦的方式。因為UI控件本身就是個node,也是按照節(jié)點樹來組織的。所以,我們可以使用類似JSON的方式,首先遞歸把所有控件名字都綁定。然后逐個處理。偽代碼如下:


綁定名字(node,owner){
  子節(jié)點數(shù)組 = node.getChildren()
  遍歷子節(jié)點數(shù)組:{
     名字key = childNode.getName()
     node[名字key]=childNode
     綁定名字(childNode)
  }
}


這樣就可以通過非常自然的"."方式訪問控件了,例如:


曾祖父控件.祖父控件.父控件.子控件.xxxxx函數(shù)()


二、動態(tài)添加接口


動態(tài)添加接口,已經(jīng)說過很多了,繼續(xù)偽碼:


首先,跟上面一樣,遞歸訪問所有子節(jié)點。


然后用分支代碼,判斷類型,為了嚴(yán)格包裝類型對應(yīng),我們使用JavaScript的構(gòu)造器來判斷:


if(child.constructor == 按鈕)
    按鈕節(jié)點的擴展函數(shù)(child)
else if(child.constructor == 文本框)
    文本框節(jié)點的擴展函數(shù)(child)
//……其他節(jié)點類型


然后我在擴展函數(shù)里直接,對相應(yīng)的child進行操作:


按鈕節(jié)點的擴展函數(shù)(child){
    child.log=function(){
        log("調(diào)用log函數(shù)成功")
    }
}


三、回調(diào)函數(shù)自動綁定


為了讓UI系統(tǒng)支持自動綁定回調(diào)函數(shù),我們可以使用一種特殊的方法。還記得CocosBuilder里面的owner么。


我們在owner上預(yù)制幾個方法,然后根據(jù)節(jié)點名字和回調(diào)函數(shù)類型,直接拼出來。以按鈕舉例:


owner.touchEventListener_按鈕名字 = function(sender, type){
    switch(type){
        case ccui.Widget.TOUCH_BAGAN:
            log("按鈕名字 TOUCH_BAGAN")
        case ccui.Widget.TOUCH_MOVED:
            log("按鈕名字 TOUCH_MOVED")
        case ccui.Widget.TOUCH_ENDED:
            log("按鈕名字 TOUCH_ENDED")
        case ccui.Widget.TOUCH_CANCELED:
            log("按鈕名字 TOUCH_CANCELED")
    }
}


因為JavaScript的缺陷,不能拿到當(dāng)前控件的類型名。還好CocoStudio提供了一個getDescription()接口,里面能夠返回一個可用的類型名。然后我們使用拼接方式綁定他:


按鈕名字 = child.getName()
fnName = "touchEventListener_" + 按鈕名字
child["addEventListener"+child.getDescription()](owner[fnName],owner)


另外,owner最好使用代碼生成器做出來,這樣可以做到全自動化了。


最后


上面這些寫法,適用于任何腳本語言,JS能用,lua也沒有問題。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI