V7投稿 | CocosCreator开源框架oops-framework 之 多语言(九)

引擎: CocosCreator 3.8.0

环境: Mac

Gitee: oops-game-kit


引言


oops-framework是由作者dgflash编写,基于CocosCreator 3.x而实现的开源框架。

该框架以插件形式存在,主要目的是为了降低与项目的耦合,并且通过插件内部的命令快速的获取最新版本。

该框架的特性有:

  • 提供游戏常用的功能库,提高开发效率
  • 提供业务模块代码模版,降低程序设计难度
  • 内置模块低耦合,可根据需要自行删减,以适应不同的类型
  • 提供了常用的插件工具,支持Excel表转Json、支持热更新、AB包
  • 增加了ECS、MVVM框架相关,以及常用的屏幕适配,UI管理,多语言等等

为了方便大家更好的学习和使用该框架,作者很贴心的准备了一些学习资料:

dgflash-哔哩视频

dgflash CSDN博客

dgflash-cocos论坛

Gitee dgflash项目仓库

注:oops-framework框架QQ群: 628575875

在CocosCreator官方商店,可以通过 oops 搜索更多的框架项目Demo进行学习。

1_2


简介


oops-framework框架提供的多语言支持:

  • 文本相关
  • 图片相关
  • 骨骼动画相关

多语言的配置在 resources/config.json 中:

{	
  "languageList": ["zh", "en", "tw"],  
	// type代表多语言的种类,path代表文本、图片等资源路径
  "language": {
    "type": [
      "zh",
      "en"
    ],
    "path": {
      "json": "language/json",
      "texture": "language/texture",
      "spine": "language/spine"
    }
  },
}

对应的资源目录如下:
9_1

注:资源目录均根据 游戏配置中的type 进行设定。


LanguageManager


多语言相关被封装在 LanguageManager 中,在 Oops.ts提供的入口主要是:

export class oops {
    /** 多语言模块 */
    static language: LanguageManager;
}

该类提供的主要参数或接口有:

参数 返回类型 说明
languages string[] 设置或获取支持的语言列表,比如: [“zh”, “en”]等
default void 设置默认语言,如果没有则默认为"zh"
current string 获取当前语言
pack LanguagePack 获取当前语言包
isExist(lang) boolean 检测指定语种是否存在
setLanguage() void 设置当前语言
getLangByID(lableId) string 获取文本对应的多语言内容
loadLanguageAssets(lang) void 下载指定语言包
releaseLanguageAssets(lang) void 释放指定语言包

简单的示例:

// 获取多语言文本内容
let content = oops.language.getLangByID("loading_load_game");
this.label.string = content;

// 设置指定类型语言,并释放其他类型
let curLanguage = oops.language.current;
if (curLanguage !== "zh") {
  oops.language.setLanguage("zh", (sucess) => {
    if (sucess) {
      oops.language.releaseLanguageAssets("en");
    }
  })
}

LanguagePack语言包

LanguagePack语言包是LanguageManager的关键接口,主要做的事情就是对文本、图片、骨骼动画进行加载、刷新和释放。 简要的看下代码相关:

export class LanguagePack {
  json: string = "language/json";				// JSON资源目录
  texture: string = "language/texture";	// 纹理资源目录
  spine: string = "language/spine";			// SPINE资源目录

  // 刷新
  updateLanguage(lang: string) {
    let rootNodes = director.getScene()!.children;
    for (let i = 0; i < rootNodes.length; ++i) {
      // 更新所有的LanguageLabel节点
      let labels = rootNodes[i].getComponentsInChildren(LanguageLabel);
      for (let j = 0; j < labels.length; j++) {
        labels[j].language();
      }
      // ...
    }
  }

  // 下载对应语言包资源
  async loadLanguageAssets(lang: string, callback: Function) {
    await this.loadTexture(lang);
    // ...
    callback(lang);
  }
  
  // 释放对应语言包资源
  releaseLanguageAssets(lang: string) {
    let langTexture = `${this.texture}/${lang}`;
    oops.res.releaseDir(langTexture);
    Logger.logView(langTexture, "释放语言 texture 资源");
    // 
  }
}

初始化

多语言的初始化及语种的设定,在项目启动时执行的,主要代码如下:

// ../initialize/bll/InitRes.ts
entityEnter(e: Initialize): void {
	var queue: AsyncQueue = new AsyncQueue();

	// 加载自定义资源
	this.loadCustom(queue);
	// 加载多语言包
	this.loadLanguage(queue);
	// ...
}

// 主要用于加载多语言对应的字体文件,比如ttf等
private loadCustom(queue: AsyncQueue) {
  queue.push(async (next: NextFunction, params: any, args: any) => {
    oops.res.load("language/font/" + oops.language.current, next);
  });
}

// 主要用于下载对应语种资源
private loadLanguage(queue: AsyncQueue) {
  queue.push((next: NextFunction, params: any, args: any) => {
    // 从本地存储中获取语言,如果为空则默认中文
    let lan = oops.storage.get("language");
    if (lan == null || lan == "") {
      lan = "zh";
      oops.storage.set("language", lan);
    }
    // 设置语言包路径
    oops.language.pack.json = oops.config.game.languagePathJson;
    oops.language.pack.texture = oops.config.game.languagePathTexture;
    // 加载语言包资源
    oops.language.setLanguage(lan, next);
  });
}

注: loadCustom的执行一定要在loadLanguage的前面,否则会导致使用字体文件的文本无法正常显示。


多语言组件


框架针对于针对于文本、图片、骨骼动画提供了不同的组件支持,主要有:

资源 组件名
文本 LanguageLabel
图片 LanguageSprite
骨骼动画 LanguageSpine

注: 这些组件都可以在属性检测器中搜索并进行添加。

9_2


继承结构如下:

9_3

这三个组件都有这一个共同的属性就是 dataID, 通过设定 dataID设定languageID即可完成多语言的赋值。下面分类说明下:

文本

文本组件的使用,如下图所示:

9_4

文本数据的获取,主要有两块:

  1. language/json 目录中获取,主要内容类似:
// zh.json
{
    "common_prompt_ok": "确定",
    "common_prompt_cancal": "取消",
    "common_prompt_title_sys": "系统提示",
    "common_prompt_content": "系统提示内容",
}
  1. 从Language.xlsx表中获取,内容如下图:

9_5

获取的顺序是先从Json中获取,如果没有则从Excel表中获取。

注:Json目录中存放的相当于必备资源,可理解为热更新前的显示,而Excel表中的获取可理解为热更新之后的显示。

框架针对于这种获取,所做的处理,主要在LanguageData.ts中,主要代码如下:

// LanguageData.ts
export class LanguageData {
  static current: string = "";	// 当前语言
  static json: any = {};				// 语言JSON配置数据
  static excel: any = null!;		// 语言EXCEL中的配置数据

  public static getLangByID(labId: string): string {
    var text = this.json[labId];
    if (text) {
      return text;
    }

    if (this.excel) {
      var record = this.excel[labId];
      if (record) {
        return record[this.current];
      }
    }

    return labId;
  }
}

使用示例:

// 方式1: 获取多语言文本内容
this.label.string = oops.language.getLangByID("loading_load_game");

// 方式2: 为文本组件添加多语言支持
@property(Node)
labelNode: Node = null!;

private showContent(content: string, isI18n: boolean = true) {
  let label = this.labelNode.getComponent(Label);
  if (label) {
    label.string = content;
  }
  
  // 使用多语言
  if (is18n) {
    let languageLabel = this.labelNode.getComponent(LanguageLabel) || this.labelNode.addComponent(LanguageLabel);
    if (languageLabel) {
      languageLabel.dataID = content;
    }
  }
}

// 方式2: toast提示, 第二个参数一定要为true
oops.gui.toast("loading_load_game", true);

精灵

精灵组件的使用,如下图所示:

9_6

注: dataID的设定就相当于纹理名字


骨骼动画

骨骼动画组件的使用,如下图所示:
9_7

最后,祝大家学习生活工作愉快!