cocos2d線上項目落地微前端

一.背景

目前cocos2d遊戲最主要的開發方式是經過官方提供的GUI圖形界面工具——creator,經過 creator 開發者無需關注構建自己,只需經過界面操做便可對遊戲代碼進行構建打包。可是這樣也存在着如下幾個問題:html

  • 構建閉源,致使開發者對項目構建沒法定製化,假如編譯出來的代碼存在兼容性問題,那隻能進入 creator 安裝目錄尋找對應的某個配置文件進行修改,這種侵入性的修改頗有可能會引起不穩定性。
  • 沒法使用其餘構建工具進行打包,意味着項目沒法使用新的技術方案,只能侷限於 creator 設定的框架之中
  • 遊戲組件在不一樣項目之間難以複用,組件一般包含了 prefabsprite 等資源,如何發佈託管並在其餘項目複用組件,簡單地經過 creator 是沒法作到的。經過 EMP微前端的方案 能從根本上解決這些問題

經過這些問題讓咱們有了一種想法,有沒有可能經過其餘構建工具打包的代碼,也能關聯到 creator 的項目中,這樣也能在creator cocos2d項目中引入EMP,從而解決組件複用的問題前端

二. creator項目接入webpack模型

首先看看單一 creator 的開發過程,它會在本地服務開啓 7456 的端口服務,整個本地開發流程以下圖:vue

image

接入 webpackemp 後的開發過程,首先 webpack 會經過 axios 抓去 creator服務生成出來的 index.html文件做爲 template,並開啓一個新的服務,並經過 devServer 將資源請求轉發回 creator的端口服務,確保資源訪問正常,開發流程圖以下:node

image

三. 接入流程

step1

全局安裝 @efox/emp-cli,經過 emp init 初始化遊戲種子工程,選擇 cocos2d 模版react

yarn add --global @efox/emp-cli && emp init

step2

在根項目經過命令 yarn 安裝依賴webpack

step3

安裝 creator cocos 開發工具 ,打開 cocosDashboard, 導入剛剛的遊戲模版項目,而後打開項目,下面是導入成功後的開發工具截圖;ios

image

複製開發工具上方提示的本地調試連接到瀏覽器上,呈現出來的界面以下,能夠看到右方console出現報錯的狀況,這是由於目前打開的只是 creator 開啓的本地服務,而項目引入了 webpack 構建的代碼,因此暫時會出現報錯的狀況;git

image

step4

進入項目根目錄,運行 yarn devgithub

瀏覽器會自動打開新端口服務,這個本地服務就是 webpack 代理 creator cocos 後的服務,經過下圖看到console已經沒有報錯了,而且界面上的 Hello World擁有了漸變背景色,這個漸變背景色實際上就是一個 Game Component,是經過 webpack 構建並注入到遊戲項目中引入的;web

image

ps: 必須先經過creator cocos開啓項目,再運行 yarn dev,由於 webpack 編譯時須要經過 axios 抓取 creator cocos 服務模版;

四. 項目代碼分析

emp-config.js

// cocos2d emp配置
const withCocos2d = require('@efox/emp-cocos2d')
const ip = require('ip')

module.exports = withCocos2d(
  ({config, env, empEnv}) => {
    // webpack本地服務端口
    const port = 9000
    const projectName = 'empCocos2dDemo'
    const host = ip.address()
    const publicPath = `http://${host}:${port}/`

    config.plugin('mf').tap(args => {
      args[0] = {
        ...args[0],
        ...{
          name: projectName,
          library: {type: 'var', name: projectName},
          filename: 'emp.js',
          // remotes: {
          //   '@emp-game/base': 'empGameBase',
          // },
          exposes: {
            // 將當前項目的component expose出去給其餘項目使用
            './components': 'src/components',
          },
        },
      }
      return args
    })

    config.output.publicPath(publicPath)
    config.devServer.host(host)
    config.devServer.port(port)
  },
  {
    // creator開啓的服務端口
    creatorPort: 7456,
    // 引用基站資源連接
    empJs: [],
  },
)

src/index.ts

webpack 的代碼如何注入到 creator cocos 代碼中,靠的是 cc 這個全局變量,cc 變量是cocos2d引擎暴露在全局的,包含了所有的引擎方法;creator cocos 接入 emp 的關鍵點就是在 cc全局變量上建立一個 EMP 屬性,這樣後續不管遠程組件模塊,抑或是本地構建的module, 均可以附值在 cc.EMP 上,從而在遊戲代碼中引入;

cc這個全局變量是cocos2d引擎暴露在全局的,這裏也分爲本地環境和生產環境的狀況,這是由於本地環境cocos2d引擎腳本是同步加載的,而生產環境是異步的,這就是爲何下面代碼判斷了 window.boot 是否存在的狀況,附值 cc.EMP 的操做是須要 cc 存在才能進行;

import Components from 'src/components'

export type EMPData = {
  Components: typeof Components
}

const EMP: EMPData = {
  Components,
}

// 關鍵部分
// 生產環境 cocos2d腳本異步加載後 再執行window.boot
// 經過重寫 window.boot 在函數體內進行cc.EMP附值,再執行原函數,確保遊戲代碼運行時 cc.EMP正常有值
if (window.boot) {
  const fn = window.boot
  window.boot = async function () {
    cc.EMP = EMP
    fn()
  }
} else {
  // 本地環境 直接附值
  cc.EMP = EMP
}

assets/Script/HelloWorld.ts

看回遊戲代碼,瞭解遊戲代碼是如何引入外部組件的

const {ccclass, property} = cc._decorator

@ccclass
export default class Helloworld extends cc.Component {
  @property(cc.Label)
  label!: cc.Label

  onLoad(): void {
    // 經過cc.EMP獲取Component模塊
    // 再經過Component模塊拓展出漸變背景色組件
    const {colorGrad} = cc.EMP.Components
    // 獲取labelNode 節點
    const labelNode = cc.find('labelNode', this.node)
    const label = cc.find('label', labelNode)
    // 經過addComponent添加漸變背景色,並設置腳本屬性 _colors
    labelNode.addComponent(colorGrad)._colors = [
      cc.Color.WHITE.fromHEX('#ffffff'),
      cc.Color.WHITE.fromHEX('#5A51FF'),
      cc.Color.WHITE.fromHEX('#8668FF'),
      cc.Color.WHITE.fromHEX('#5A51FF'),
    ]
    setTimeout(() => {
      // 重設labelNode節點寬高
      labelNode.setContentSize(label.width, label.height)
    })
  }
}

五. 已有項目如何接入

接入步驟以下:

  1. 在根項目安裝 emp 相關依賴;
yarn add -D @efox/cli
yarn add -D @efox/emp-tsconfig
yarn add -D @efox/emp-cocos2d
  1. package.json 添加以下片斷:
{
    ...,
    "scripts": {
        ...,
        + "dev": "emp dev",
        + "build": "emp build --ts --env prod && cp -r ./dist/. ./build/web-mobile"
    }
}
  1. 根目錄建立 emp-config.js,並複製如下內容
const withCocos2d = require('@efox/emp-cocos2d')
const ip = require('ip')

module.exports = withCocos2d(
  ({config, env, empEnv}) => {
    const port = 9000
    const projectName = 'empCocos2dDemo'
    const host = ip.address()
    const publicPath = `http://${host}:${port}/`

    config.plugin('mf').tap(args => {
      args[0] = {
        ...args[0],
        ...{
          name: projectName,
          library: {type: 'var', name: projectName},
          filename: 'emp.js',
          // remotes: {

          // },
          exposes: {

          },
        },
      }
      return args
    })

    config.output.publicPath(publicPath)
    config.devServer.host(host)
    config.devServer.port(port)
  },
  {
    // creator開啓的服務端口
    creatorPort: 7456,
    // 引用基站資源連接
    empJs: [],
  },
)
  1. tsconfig.json 替換以下內容:
{
  "extends": "@efox/emp-tsconfig",
  "compilerOptions": {
    "experimentalDecorators": true,
    "baseUrl": "./"
  },
  "include": ["src", "creator.d.ts", "index.d.ts", "assets"]
}
  1. 建立 src 目錄,並新建 index.ts
export type EMPData = {}

const EMP: EMPData = {}

if (window.boot) {
  const fn = window.boot
  window.boot = async function () {
    cc.EMP = EMP
    fn()
  }
} else {
  cc.EMP = EMP
}
  1. 建立 index.d.ts,定義 cc.EMP 類型聲明
import {EMPData} from './src'

declare global {
  namespace cc {
    export let EMP: EMPData
  }
  interface Window {
    boot: () => void
  }
}

六. 總結

目前 creator cocos 遊戲開發只能依賴官方開發工具,接入這套模型,能使得項目定製化更加便捷,且具備如下優勢:

  1. 幾乎零成本接入

首先看看接入 emp 後的 creator cocos項目目錄結構

image

由上圖能夠看出,與 普通的creator cocos2項目 相比,只多瞭如下2個文件1個目錄

  • src/*
  • emp-config.js
  • index.d.ts

無需改變原遊戲代碼任何的部分,作到了幾乎0成本接入

  1. 將開發方式迴歸到咱們熟悉的步伐上,且更靈活,本來的開發方式是GUI工具製做 一個一個 prefab,再寫一個一個腳本綁定進去,雖然操做簡單,但開發體驗很很差,接入模型後,GUI工具依然負責製做 prefab,但腳本就能夠抽離出來由webpack構建,這能給編寫的腳本帶來更多的新特性,豐富開發方式;

  2. 組件開發靈活,多項目共享,當前開發遊戲組件只能在當前項目複用,若是其餘遊戲項目也想用呢?這時可能會想到發佈到官方託管的倉庫或者npm倉庫,可是有個問題,若是這個組件依賴了圖片,那發佈到npm倉庫多是一個難題;emp基站的模型能很好地解決這些問題,由於自己遊戲項目就是一個基站,其餘遊戲項目能夠輕鬆複用其餘遊戲 expose 出來的組件

不一樣遊戲項目之間組件的互相調用,能夠參考 EMP中的cocos2d

基於Webpack 5 Module Federation實現的 EMP微前端方案creator cocos這種閉源的開發過程都能接入 EMP,證實這套方案並不侷限技術棧;若是是剛開始接觸微前端的話,能夠嘗試去了解一下,能夠帶給你很好的使用體驗喔

具體的EMP微前端方案教程目錄以下:

相關文章
相關標籤/搜索