CocosCreator遊戲開發框架(一):是什麼 && 爲什麼

寫在前面


從微信小遊戲出生(2018年初)到現在,已經使用CocosCreator一年多了(之前做手遊主要是cocos2d-x+lua),趁着這段時間有空,想着整理出一個基於CocosCreator遊戲開發框架

這個框架主要是將我在開發過程中覺得好用的結構和模式、插件,以及在論壇上和博客上參考大神們的教程和想法(有些是直接拿來用),整合在一起的。一方面想提高開發效率,另一方面大家發現問題及時提出及時討論,慢慢優化和改進。

框架工程是否跟遊戲工程分開

在開始之前,因爲這個問題糾結了好久。框架工程跟遊戲工程分離,框架工程作爲一個獨立代碼庫,僅僅作爲遊戲工程的子模塊,這樣代碼庫可以統一管理。

我上個項目就是這樣做的,但是你會發現,把框架模塊單獨拿出來給下一個項目複用,裏面有一些耦合了遊戲工程的代碼。如果要每個成員在緊張的遊戲開發過程中保持清醒,去保持框架模塊的獨立性,肯定是一個蛋疼的過程。

後來閱讀了兩篇文章(關於遊戲設計模式的)之後,確定了該框架僅僅作爲一個“純淨”的基礎框架,每開一個新項目就拷貝過去,然後根據遊戲的需求自己去調整。

兩篇文章的鏈接在下面,有興趣的可以瞭解下,不扯遠了,準備進入正題!

【遊戲設計模式】之一 序言:架構,性能與遊戲

爲什麼在遊戲開發中我不喜歡用MVC系列模式了




正文


目錄細分和規劃

如下圖:
project_dir

  • animClip:存放動畫文件(.anim)
  • font:存放字體文件
  • prefab:存放不需要動態加載的預製體
  • texture:存放用於貼圖資源
  • texture/ui_common:存放公用的ui資源圖集文件。
  • texture/ui_module:每個功能/模塊單獨用到的資源打包後的圖集文件,比如main場景單獨用到的打包一起,然後mian場景勾選自動釋放資源,切換場景時就會自動釋放沒用的資源(前提是沒有被其他的地方引用到)。
  • resources:存放一切需要用於動態加載(cc.load.loadRes)的資源

爲什麼有些資源放在resources裏面,有些放到外面?

先看官網的解釋:
resource_desc

總結一下:

1、resources文件夾中的資源可以跟它外部的其他資源,相互引用,所以放哪,問題不大。
2、只有放在resources文件夾的資源才能用cc.loader.loadRes動態加載。
3、構建時,resources文件夾中的所有資源連同它們關聯依賴的resources文件夾外部的資源,都會被導出,並且項目中無用的資源將會在構建的過程中自動剔除。
4、resources文件夾的資源,會增大包體和settings.js的大小,JSON的自動合併策略也將受到影響,無法儘可能將零碎的JSON合併起來。




框架模塊介紹


# 配置表模塊

直接在現有的插件excel-killer的基礎上做了小調整。

  • 相關目錄(可以根據需求自己改動,相關文件:packages/excel-killer/panel/index.js)

plugins-excel/excel:存放excel表

plugins-excel/excel-ouput: 存放執行插件後的js輸出文件

assets/script/data/config: 執行插件後,會自動把js文件從plugins-excel/excel-ouput拷貝到此目錄


  • 如何使用
let cfgman = require('CfgMan');
console.log(cfgman[1].name);  // 小明



# 數據模塊

  • 目錄結構

IDataModel.ts:數據模塊基類,主要功能:讀取數據表、讀寫本地緩存數據、網絡數據交互


  • 本地緩存數據接口

LoadStorage():將該模塊的本地緩存數據讀取到內存

Query(sKey: string, defaultValue: any = null):訪問指定鍵名的值

Set(sKey: string, value: string | number):設置指定鍵名的值

Save():保存內存數據到緩存文件


  • 網絡數據交互接口

sendProtocolMsg(msg):發送協議到服務端

registerListeners():註冊網絡監聽事件,需要在getMessageListeners()定義需要監聽的協議和方法

// AccountModel.ts
getMessageListeners() {
    return {
        // key:消息名,value:執行函數
        ['G2C_Login']: (msg) => { this.G2C_LoginSuccess(msg) },
    }
}



# UI模塊

  • 目錄結構

UIMng:UI管理器,用於打開、關閉UI

UIBase:UI界面基類,在這裏可以定義一些通用方法,供子類調用或者繼承

UIHelp:UI工具類,封裝一系列UI相關的功能方法


  • 如何使用(配合自動化插件)

1、新建一個場景或者prefab

2、選中,然後到工具欄:擴展 -> auto-ui

  • export操作:將prefab節點樹的結構自動導出到ts文件(目標文件夾:assets/script/data/autoui)
export default class auto_notice extends cc.Component {
	notice: cc.Node;
	background: cc.Node;
	title: cc.Node;
	content: cc.Node;
	btnClose: cc.Node;
	public static URL:string = "db://assets/resources/prefab/notice/notice.prefab"

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
		this.notice = this.node
		this.background = this.notice.getChildByName("background");
		this.title = this.notice.getChildByName("title");
		this.content = this.notice.getChildByName("content");
		this.btnClose = this.notice.getChildByName("btnClose");

	}
    start() {}

    // update (dt) {}
}

以後,你想要使用ui節點,就不需要各種getChildByName,或者搞個property在編輯器拖,所有的節點都導出在一個ts文件,然後作爲一個組件添加到UI文件中,你只需要this.ui[節點名稱]即可訪問。

  • create-script操作:自動生成UI模板TS文件

3、將第2步create-script操作生成的UI腳本文件,在編輯器拖到prefab的根節點作爲組件

4、UI的基本操作都封裝在UIHelp中

UIHelp.ShowUI(UINotice);    // 打開ui
UIHelp.CloseUI(UINotice);   // 關閉ui
UIHelp.SetLabel(this.ui.title, '測試公告標題'); // 修改label節點文本

  • TODO

1、後續補充關閉UI清除相關無用資源

2.、目前的插件代碼太亂,後面會嘗試整理


  • 這裏說一下對於UI的一些想法和見解

1、MVC模式。在框架中,每一個功能創建一個model類繼承IDataModel,用於處理數據(配置表、本地數據、網絡數據)。新建的prefab就是view,掛載在prefab的腳本組件就是controller,在controller實現功能邏輯。

2、很多人在用CocosCreator開發時,經常會往節點上掛腳本,往按鈕上綁定事件(看過好多github上的項目都是這樣)。但我個人是很不建議這樣做的,正常的團隊開發合作中都是分工明確的,比如你在編輯器中用按鈕綁定事件,難道美術修改的時候還要關心代碼麼。而且任意節點都可以掛腳本,這個真的有點“災難性”,我要找在這個腳本在哪裏用到的時候還要去編輯器一個個找麼(可能有其他快速查找的方法,我不知道的,請指點一下)。

3、所以我是比較支持,能用代碼實現的儘量用代碼實現,腳本文件能掛在根節點(方便找)的儘量掛在根節點。




# 網絡模塊

數據協議用Protobufjs,網絡協議用WebSocket

CocosCreator使用protobufjs,具體教程點這裏

  • 目錄結構

ProtoBuf.ts:對protobufjs的修改和封裝

ProtoLoader.ts:用於加載proto文件

Message.ts:proto msg的基類,並將msg緩存起來

ProtoMessage.ts:插件根據proto文件生成的代碼

Socket.ts:WebSocket/WxSocket的具體實現

SocketDelegate.ts:Socket代理類,根據具體平臺創建socket,提供統一回調接口供具體Socket調用

Network.ts:網絡的邏輯實現,跟用戶打交道,連接網絡、關閉網絡、登錄流程、斷網、重連都可以在這裏處理




# 日誌模塊

  • 增加開關配置,每個大功能可以有一個開關,每個開發人員可以有一個開關,按需定義
export const LOG_TAG = {
    SOCKET: { desc: 'LOG_SOCKET', isOpen: true },
    TEST: { desc: 'LOG_TEST', isOpen: false },
}

  • 使用
Log.log(LOG_TAG.SOCKET, 'socketprint');
Log.warn('warn');
Log.error('error');

log方法第一個參數爲開關分類,warn和error沒有,因爲我認爲一般調試打印用log方法就夠了,如果你用warn或error,肯定是需要所有人都知道的。




# 事件模塊

EventMng.ts:事件分發我偷懶了,直接new一個cc.EventTarget來用,目前沒有發現其他問題。




# 其他

GameController.ts:遊戲全局控制類,比較雜的不知道放哪的可以看看能不能放這裏

GameDataCenter.ts:管理遊戲各個模塊數據

global.d.ts:用於擴展基礎模塊

utils文件夾:用於存放一些工具類





最後


這篇文章講的主要是框架有什麼東西,有些地方爲何要這麼設計,githu工程點這裏

看完有點懵逼?沒關係,下篇文章是:CocosCreator遊戲開發框架(二):怎麼用

我會在框架的基礎上快速開發一個簡單的客戶端登陸系統,幫助大家快速上手。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章