1. 程式人生 > >使用CocosCreator進行Cocos2d-JS開發之第一彈

使用CocosCreator進行Cocos2d-JS開發之第一彈

本節原始碼下載:

觸控科技開發的CocosCreator開發工具是的Cocos2d開發和Unity開發更加相似,使用CocosCreator開發2d遊戲變得更加便捷快速,之後半年利用做畢業設計的閒暇之餘學習使用Cocos Creator開發2d的遊戲,主要是看觸控科技官方提供的ExampleProject的原始碼來大致的模仿實現:

Cocos2d-JS開發的第一彈中,首先開發一個下面的介面:


[說明]

點選Menu的按鍵(綠色按鍵)會有事件相應,點選List的某一Item會有相應的事件相應。

專案的結構:

          

(一)繪製背景Sprite([層級管理器]中的background元件)

background為一個Sprite,在[層級管理器]中 建立Sprite精靈,選中該Sprite精靈之後,在[屬性檢查器]中修改Sprite的屬性:


(1)將選中的背景圖片(e.g. singleColor.png)從[資源管理器]中通過拖拽的方式新增到Sprite的[Sprite Frame]屬性框中;

(2)在[新增元件]處為Sprite新增Widget屬性(新增元件-新增UI元件-Widget):


[說明]Widget的作用是為了使得元件更好的適配父節點的大小,其中的Left,Top,Right和Bottom分別為該元件相對於父節點左邊緣,上邊緣,右邊緣和下邊緣的距離,可以使用px直接指定,也可以使用10%這樣來制定是父節點長/寬度的百分比,這四項中打勾的表示該項起作用,下邊的Horizontal Center和Vertical Center將會相對於父節點的橫向置中,和垂直置中。

經過上面的步驟,就完成了背景Sprite的繪製。

(二)繪製選項節點([層級管理器]中的Menu元件)

(1)在Canvas節點中建立Menu元件(為Sprite元件,並設定Widget屬性,讓其鋪滿父節點Canvas),並在[屬性管理器]中Sprite的Sprite Frame屬性框中設定為None:


這樣Menu鋪滿父節點Canvas,但不會覆蓋父節點的背景。

(2)在Menu節點中新建兩個Button節點([層級管理器]中的btnBack和btnInfo),Button元件預設帶一個Label子節點,選中Label元件,可以在[屬性檢查器]中Label-String屬性處修改 按鍵上文字內容:


選中Button元件之後,在[屬性檢查器]中可以看到一個Button元件預設有Sprite屬性和Button屬性,那麼可以通過從[資源管理器]中拖拽圖片的方式,新增到Button元件的Sprite屬性的Sprite Frame屬性框中,從而改變Button元件的背景圖片:


拖拽圖片到Button的Sprite屬性的Sprite Frame框後,可以看到Button的背景圖片改變了,但是Button的邊框出現模糊,這是因為Button的尺寸大於圖片的尺寸,從而出現了模糊現象,此時我們展開[資源管理器]中Texture資料夾中對應的圖片檔案,雙擊可以開啟[Editor Window]對話方塊處理圖片:


拖拽[Editor Window]中圖片上的四條綠色的線,來設定圖片的屬性,{完成這一修改之後,一定要點選[Editor Window右上角綠色的對號進行屬性儲存]},至於為什麼要這麼修改,其實就和Android開發中的9patch圖片的原理一直,當元件的尺寸大於圖片尺寸的時候,要對圖片進行拉伸,這四條線表示只拉伸四條線圍成矩形框內的畫素點,矩形框外部的畫素點不會被拉伸,只會保持原來圖片的畫素。

完成上面的操作之後,還需要將Button元件的Sprite屬性的Type屬性選項修改為SLICED:


這樣,我們的按鍵的效果看起來就舒服多了:


(3)完成上述操作之後,分別為兩個Button節點在[屬性檢查器]中新增Widget屬性(新增元件-新增UI元件-Widget),將兩個Button元件放置在介面的左上角 和 右上角,以[檢視說明]Button為例(在介面的左上角):


(4)為Button新增點選效果

完成上面所有的操作之後,執行,在網頁上點擊發現按鍵並沒有點選效果,如何做到點選的時候會有點選效果,選中Button元件,在[屬性檢查器]中Button屬性下面可以看到:

上圖一中,Button屬性的Transition屬性選擇框,有None,SPRITE,COLOR,SCALE四個選項,可以設定Button被點選的效果,None表示沒有點選效果(預設),SPRITE表示點選效果使用Sprite精靈來展示,COLOR表示點選效果使用顏色變化來展示,SCALE表示Button被點選的時候改變其大小,下面以COLOR為例:


上圖中,Normal表示常態Button的顏色,Pressed表示Button被按下的顏色,Hover表示滑鼠移動到該Button上之後Button的顯示狀態,按需求點選顏色選擇條進行顏色設定。

(5)為Button新增點選相應事件_需要js指令碼

首先在[資源管理器]中assets/Script檔案下新建一個名為Menu.js的指令碼檔案,新建完成之後,開啟指令碼檔案會發現,檔案根是一個cc.Class,這是cocosJS中的類的宣告方式,內部有:

extends: cc.Component,

properties: {
        
}
其中,extends表示該類即成自cc.Component元件,properties中宣告該類的本地變數,以後可以通過this.propertyName來進行引用。除此之外,一個重要的函式為onLoad方法,當該類被載入的時候,就會呼叫此方法,可以在其中做一些初始化的操作,我們在Menu.js中新增如下的程式碼:
cc.Class({
    extends: cc.Component,

    properties: {
        btnInfo: {
            default: null,
            type: cc.Button
        },
        btnBack: {
            default: null,
            type: cc.Button
        }
    },

    backToList: function(){
        cc.log("backToList Button Clicked!")
    },

    showReadme: function(){
        cc.log("showReadme Button Clicked!")
    }
});

新增完上面的程式碼之後,我們將該指令碼檔案新增給Menu節點:

[方法一]:在[層次管理器]中點選中Menu節點,此時[屬性檢查器]中顯示Menu節點的屬性,從[資源管理器]中拖拽Menu.js指令碼到[屬性管理器]進行指令碼新增;

[方法二]:在[層次管理器]中點選中Menu節點,此時[屬性檢查器]中顯示Menu節點的屬性,點選 新增元件-新增使用者指令碼元件,便可以看到 已經在[資源管理器]中新增的所有的指令碼檔案,點選需要新增的Menu.js檔案:


從[層級管理器]中拖拽對應的元件到上圖中的 Btn Info屬性框和Btn Back屬性框中進行資料新增:


接下來,在[層級管理器]中點選中btnBack元件,在[屬性檢查器]中修改按鍵的屬性,在Button屬性欄中,首先將Click Events屬性框修改為1,表示為Button繫結一個Click事件,此時就會出現 [0]事件編號,將[層級管理器]中的Menu節點拖拽新增到第一個屬性框中(cc.Node),點選後面第一個下拉選單,可以看到Menu節點上繫結的所有指令碼,選中Menu.js的指令碼,再繼續點選後面的下拉框,可以看到Mneu.js指令碼檔案中已經新增的函式,選擇事先寫好的Btn Back的Click相應函式,這樣就為[層級管理器]中的btnBack按鍵綁定了Click事件:


(三)繪製MenuList節點

首先給Canvas節點新增一個ScrollView元件,可以看到,ScrollView包含兩部分,一個scrollbar,另一個是content,即為List內容顯示部分,為了讓ScrollView元件能夠更好的適配父節點的大小,通過為ScrollView,子節點view以及content設定Widget屬性控制其大小,讓元件鋪滿整個父節點:


需要說明,view節點是ScrollView顯示區域,一般的要和ScrollView的大小一致,或比ScrollView稍小,以便能夠看到List中的全部內容,view的位元組點content是ScrollView將要顯示的全部內容,其大小可以大於ScrollView和view,也可以小於,大於父節點大小之後,便可以通過拖拽來檢視view之外的部分,所以一般不勾選content的Widget屬性中Bottom屬性項。

(1)首先繪製ListItem,並製作Item-Prefabs

在[場景繪製器]中繪製MenuList中單個Item,在content新增一個Sprite位元組點,通過拖拽修改Sprite的Sprite Frame中的背景圖片,為了讓圖片不出現失真的情況,需要對圖片進行Editor:


為了讓Item可以顯示 文字資訊,可以為其 新增一個Label位元組點,並在[屬性檢查器]中修改 Label的Color,修改文字顏色,為Label新增Widget屬性,讓Label適配父節點,需要注意的是,要修改Label的的Overflow屬性為CLAMP,Label才能夠鋪滿父節點:


完成上面的步驟之後,在[層級管理器]中可以看到Item的結構:


將上面的mainMenuItem拖拽到[資源管理器]中assets/Prefabs資料夾下,同時刪除[層級管理器]中mainMenuItem節點:


這樣就完成了Prefab的製作,下面再為Prefab新增一個控制指令碼,為不同index的Item設定不同的內容(mainMenuItem.js):

cc.Class({
    extends: cc.Component,

    properties: {
        label: {
            default: null,
            type: cc.Label
        },
        index: -1
    },

    updateItem(index, name){
        this.index = index;
        this.label.string = name
    },

    itemClickedEvent: function(){
        cc.log(this.index)
    }
});

上面的程式碼中,為每一個Prefab設定了兩個property屬性,一個是顯示內容的Label元件,另外一個是該Prefab-Item的index,例項化Prefab-Item之後,呼叫物件的updateItem方法來顯示內容,並定義了Item被點選的響應事件,在[資源管理器]中雙擊選中assets/Prefabs/mainMenuItem,並將上面的指令碼檔案mainMenuItem.js拖拽新增到mainMenuItem-Prefab的屬性管理器中,並將mainMainItem的位元組點labelContent拖拽到指令碼檔案的Label屬性框中:


為了讓每一個Item有點選事件,還需要給每個Item-Sprite新增一個Button屬性,並修改Click Events屬性設定,在[資源管理器]中雙擊選中assets/Prefabs/mainMenuItem,在[資源管理器]中通過 新增元件-新增UI元件-Button  來新增:


(2)為ScrollView動態的新增Item

ScrollView中顯示的Item都是新增到其content節點中的,所以需要編寫js指令碼檔案,進行動態新增(SceneList.js):

cc.Class({
    extends: cc.Component,

    properties: {
        itemPrefab: {
            default: null,
            type: cc.Prefab
        },
        initItemCount: 0,
        scrollView: {
            default: null,
            type: cc.ScrollView
        },
        bufferZone: 0,
        itemContents: []
    },

    init(menu) {
        this.menu = menu;
        this.itemContents = this.getMainMenuContent();
        this.initList();
    },

    initList(){
        var count = this.itemContents.length
        for (let i = 0; i < count; i++){
            // 通過cc.instantiate方法生成了一個Prefab節點
            let item = cc.instantiate(this.itemPrefab);
            // 獲得節點上的名稱為mainMenuItem的屬性,這裡就是該Prefab物件的指令碼熟悉
            // 因為指令碼檔案中包含了 Prefab 內容顯示的元件,所以可以通過該指令碼屬性完成很多事情
            var itemComp = item.getComponent('mainMenuItem')
            // 直接呼叫指令碼屬性的動態方法,來操作Prefab物件
            itemComp.updateItem(i, this.itemContents[i])

            // 下面是通過指令碼屬性獲得 顯示內容的元件,
            // 從而改變元件顯示的內容
            // var label = itemComp.label
            // label.string = this.itemContents[i]
            this.scrollView.content.addChild(item)
        }
    },

    // 自定義的指令碼檔案,獲取 場景Scene的列表,
    // cc.game.__sceneInfos可以獲取得到
    getMainMenuContent(){
        var array = ["第一個場景", "第二個場景", "第三個場景", "第四個場景", "第五個場景", "第六個場景"]
        return array
    },

    // called every frame, uncomment this function to activate update callback
    // update: function (dt) {

    // },
});

上面的程式碼中,我們可以看到,當要顯示ScrollView中內容的時候,需要例項化該cc.Component元件,並呼叫自定義的init方法來初始化列表,在initList方法中,使用了cc.instantiate方法例項話一個item-Prefab物件,並通過addChild方法將這個例項化之後的item新增給ScrollView的content節點中。

接下來,將上面的指令碼SceneList.js新增到ScrollView的content上,並從[層級管理器]中通過拖拽新增相應的屬性項:


(3)在Menu中初始化List資料:

我們想在Menu被初始化的過程中同時初始化MenuList資料,就需要在Menu的onLoad函式中例項化SceneList,並呼叫物件的自定義方法init來初始化List,修改Menu.js指令碼檔案:

Menu.js 程式碼:
cc.Class({
    extends: cc.Component,

    properties: {
        btnInfo: {
            default: null,
            type: cc.Button
        },
        btnBack: {
            default: null,
            type: cc.Button
        },
        menuList: {
            default: null,
            type: cc.ScrollView
        }
    },

    // use this for initialization
    onLoad: function () {
        // 通常只會載入一個場景,當場景發生切換的時候,預設會將原來場景中所有的節點和例項銷燬,
        // 如果我們需要某個組建進行其他場景的載入,或者在場景之間載入資料,那麼就需要將該元件
        // 標記為[常駐節點],使其不被自動銷燬,就需要呼叫cc.game.addPersistRootNode(node)

        // this.node 會獲得組建所在的節點物件
        cc.game.addPersistRootNode(this.node);
        this.node.zIndex = 999

        if (this.menuList && this.menuList.content){
            this.sceneList = this.menuList.content.getComponent("SceneList");
            this.sceneList.init(this);
            cc.log("載入完成....")
        }
    },

    backToList: function(){
        cc.log("backToList Button Clicked!")
    },

    showReadme: function(){
        cc.log("showReadme Button Clicked!")
    }
});

並將ScrollView拖拽到指令碼檔案的屬性框中:


執行專案,可以看到的效果:


發現所有的List-Item全部都疊加到了一起,因為Item都是新增到ScrollView的content子節點中的,所以需要為content子節點設定Layout屬性,在[層級管理器]中選中content節點,[屬性管理器]中通過 新增元件-新增UI元件-Layout  來添加布局屬性,並進行修改:


新增Layout屬性之後的效果: