寫於 2018.11.01html
在近期使用CocosCreator(如下簡稱CC)開發HTML5遊戲的工做中,發現公司許多遊戲都有着相同的元素,好比倒計時條、結算頁面等等。在早期的開發中,咱們並無摸索到複用的辦法,只能在不一樣的遊戲項目中從頭開始寫。隨着需求愈來愈多,重複造輪子確定不是一個好辦法,那麼對於CC項目來講,能不能把這些可複用的遊戲元素做爲組件封裝抽離出來呢?通過一番探索,終於找到了解決的辦法。git
以咱們在手Q上的「太鼓達人」小遊戲爲例子,它的倒計時條和結算頁面,在其餘的小遊戲裏面也是存在的,僅僅是外觀上有所不一樣,但當中的邏輯處理是一致的。這裏的倒計時條和結算頁面,均可以理解爲組件。typescript
兩個組件的邏輯以下:shell
倒計時條能夠設置遊戲時間,在遊戲時間內其填充長度不斷縮減;倒計時條右側會顯示所剩時間;在倒計時結束後會執行回調動做。bash
結算頁面能夠設置等級分值,達到或超過具體的等級分值能夠得到星星;星星會按照動畫邏輯展現;下方會從0開始對分數進行結算;結算完成後會執行回調動做。編輯器
經過這個例子不難理解,一個所謂的CC組件,就是一個包含了邏輯、圖片、動畫、音頻等不一樣資源的遊戲節點。在CC裏面,一個節點它長這個樣子:優化
能夠看到,編輯器左側定義了它的結構,中間是它的具體體現,右側是它的相關屬性。動畫
若是我想在其餘的項目中複用這個已經定義好的節點,應該怎麼作呢?ui
在CC裏面,預製資源是很是重要部分,能夠把它理解爲節點的模板。若是要將一個已經作好的節點抽象成組件,把它變成預製資源會是一個最合適的辦法。this
當咱們在CC編輯器定義好一個節點,給它關聯邏輯腳本、靜態資源之後,直接把它從編輯器的層級管理器
拖到資源管理器
就能夠把它轉化爲預製資源。可是因爲CC內資源的關聯是基於資源路徑的,因此在抽象一個CC組件出來以前,咱們有必要把該組件全部用到的資源都放在一塊兒,以方便之後的複用,不然極可能在其餘工程複用的時候會報找不到資源的錯誤。
新建一個CC工程,清空assets/
目錄,而後在裏面創建Components/
目錄,做爲咱們存放CC組件的目錄。以遊戲結果頁Result
爲例,按照以下目錄結構進行初始化,放入必要的資源:
.
├── Resources # 組件靜態資源
│ ├── score.png
│ └── star.png
└── Result.ts # 組件腳本
複製代碼
而後在CC編輯器中,經過拖拽的方式給子節點添加圖片,最後綁上邏輯腳本Result.ts
:
完成之後,把它拖到資源管理器的assets/Components/Result
目錄下成爲一個預製資源。
爲了讓其餘用戶可以方便地使用這個組件,因此能夠爲其添加一個demo,裏面放置着僅有這個組件的場景和場景所需的腳本。當用戶須要瞭解這個組件時,只須要預覽Demo場景便可,而組件的一些方法也能夠在Demo腳本中看到。最終目錄結構以下:
.
├── Demo # 組件使用Demo
│ ├── Result.fire
│ └── ResultDemo.ts
├── Resources # 組件靜態資源
│ ├── score.png
│ └── star.png
├── Result.prefab # 組件節點
└── Result.ts # 組件腳本
複製代碼
簡單來講,只要把組件庫工程的Components/
目錄整個複製到目標工程的assets/
目錄下,而後把預製資源節點拖到層級管理器去就能夠了。固然這樣的手動操做不夠優雅,因此咱們能夠藉助shell腳原本幫咱們簡化這個步驟。
在目標工程的根目錄下新建一個download.sh
腳本,寫入以下內容:
#!/bin/bash
# 先清理一下
echo "Clearing workbench..."
rm -rf ./cocos-components
rm -rf ./assets/Components
# 直接clone組件庫工程,取出Components目錄,而後刪掉組件庫工程
echo "Cloning project..."
git clone http://git.xxx.com/cocos-components.git
cp -r ./cocos-components/assets/Components ./assets
rm -rf ./cocos-components
echo "Done!"
複製代碼
之後只須要執行./download.sh
就能夠下載到最新的組件庫了,很是方便。
組件的設計應該遵循「黑盒子」原則,它不依賴於其餘組件,也不影響其餘組件。組件的狀態由組件自身保存,若是須要改變組件的狀態或行爲,應該經過它向外暴露可配置項或接口(經過Cocos Creator的屬性檢查器修改或者引入組件的腳本實例)。
以Progress
組件爲例。
它向外提供了gameDuration
配置項,定義倒計時的時長。另外它也提供了一個setTimeoutCallback()
的方法,用於定義當倒計時結束後的行爲。前者能夠直接在Cocos Creator的屬性檢查器裏面修改,後者則須要在遊戲腳本中經過代碼的方式去使用:
import Progress from '../Components/Progress/Progress'
@ccclass
export default class Game extends cc.Component {
start () {
Progress.instance.setTimeoutCallback(() => {
console.log('Test progress timeout callback!')
})
}
}
複製代碼
在定義組件的腳本的時候,要注意爲該腳本添加一個名爲instance
的靜態屬性,以供腳本之間的調用:
export default class Progress extends cc.Component {
static instance = null
constructor () {
super()
Progress.instance = this
}
}
複製代碼
此外,搭建組件庫必須注意命名規範,這樣不論是開發方仍是調用方,均可以省去很多的煩惱。
CC組件庫工程也是一個完整的CC遊戲,咱們能夠在這個遊戲裏面添加組件菜單,點擊菜單就能夠加載對應組件的場景,實時預覽組件的效果。這個想法也會在以後付諸實踐,爭取早日開源出來。