cocosCreator 之 i18n多语言插件

news2025/1/20 2:01:55

版本: v3.4.0

环境: Mac


简介

i18n国际化的简称, 全名:internationalization;取首尾字符in18代表单词中间的字符数目。

该插件不需要产品做太多的改变,通过语言的设置,实现不同地区之间页面的切换。

官方提供的i18n插件,支持LabelSprite的多语言国际化。

更多内容可参考: i18n 多语言支持


安装

cocos Dashboard -> 商城 -> 搜索i18n免费插件 下载成功后,如果为zip压缩包,可打开编译器的扩展管理器i18n导入进来。

然后通过终端命令进入到项目的extensions/i18n目录下, 执行安装命令:

npm install

如果安装很慢,可能是因为安装镜像为国外,导致网络卡顿,可以运行更换镜源的命令:

npm config set registry https://registry.npm.taobao.org

然后再重新运行npm install,稍等片刻,等命令执行结束后,再执行构建命令:

npm run build

安装完成后,建议重启下Creator编译器。如果发现控制台有错误,可以忽略掉,在配置完成后,错误会自动消失。


多语言配置

打开编译器,选择主菜单上的扩展 -> i18 Settings, 打开本地化控制面板

请添加图片描述

选择**+**号新增配置,比如输入zh代表中文,输入en代表英文,最后按回车键确认。

比如新增语言zh后,会在你的assets/resources目录下生成i18n\zh的配置文件。打开该文件内容:

const win = window as any;
export const languages = {
  // Data
};

if (!win.languages) {
  win.languages = {};
}

win.languages.zh = languages;

export const languages下输入内容:

export const languages = {
  "test": {
    "main": "测试",
    "hello": "你好",
  }
};

然后回到编译器,创建一个Label文本, 将资源管理器的i18n/LocalizedLabel组件拖到文本节点中。

并输入key内容test.main,如下所示:

请添加图片描述

文本内容完成替换。

然后我们通过扩展 -> i18 Settings, 打开本地化控制面板,新增en的内容相关。

// assets/resources/i18n/en.ts
const win = window as any;

export const languages = {
  "test": {
    "main": "Debug",
    "hello": "Hello",
  }
};

if (!win.languages) {
  win.languages = {};
}

win.languages.en = languages;

通过本地化控制面板的那个眼睛( i18n-display 表示当前语言, i18n-undisplay表示不显示)进行切换语言:

请添加图片描述

如此就可以实现文本多语言功能了。


图片的配置

在编译器中创建一个Sprite,然后将资源管理器/i18n/LocalizedSprite的组件拖曳到该节点下。

SpriteList 有几种语言就输入数字几,大概如图所示:

请添加图片描述

通过本地化控制面板的那个眼睛( i18n-display 表示当前语言, i18n-undisplay表示不显示)进行切换即可。


动态切换

项目运行时,需要支持语言的动态切换, 我们创建一个按钮,并增加点击事件,如下代码:

// import * as i18n from '../extensions/i18n/assets/LanguageData'
import * as i18n from 'db://i18n/LanguageData';

@ccclass('loginScene')
export class loginScene extends Component {
  // 点击多语言切换
  public clickChangeLanguage() {
    // 通过init设置当前语言类型
    if (i18n._language === "en") {
      i18n.init("zh");
    }
    else if (i18n._language === "zh") {
      i18n.init("en");
    }
    // 用于更新场景中的对应的LocalizedLabel和LocalizedSprite的内容
    // 以实现多语言的替换相关
    i18n.updateSceneRenderers();
  }
}

大概的实现原理:

  • 通过i18n.init初始化语言类型
  • 通过LocalizedLabel下的Key声明语言标记; 通过LocalizedSprite下的spriteList设置图片SpriteFrame
  • 除图片外,通过i18n.t根据当前语言类型和key想过获取文本内容
  • 最后通过i18n.updateSceneRenderers 对所有符合条件组件进行强制刷新。

简单看下代码的实现相关:

// from '../extensions/i18n/assets/LocalizedLabel'

@ccclass('LocalizedLabel')
@executeInEditMode
export class LocalizedLabel extends Component {
  label: Label | null = null;

  @property({ visible: false })
  key: string = '';

  // 声明property属性Key
  @property({ displayName: 'Key', visible: true })
  get _key() {
    return this.key;
  }
  set _key(str: string) {
    this.key = str;
    this.updateLabel();
  }

  onLoad() {
    // 初始化语言类型为zh
    if (!i18n.ready) {
      i18n.init('zh');
    }
    this.fetchRender();
  }

  fetchRender () {
    // 获取文本Label组件
    let label = this.getComponent('cc.Label') as Label;
    if (label) {
      this.label = label;
      this.updateLabel();
      return;
    } 
  }

  updateLabel () {
    // 通过LanguageData的方法接口,根据语言类型和key获取指定的内容
    // 然后改变内容的显示
    this.label && (this.label.string = i18n.t(this.key));
  }
}

里面的i18n指的就是文件LanguageData,它的主要实现:

// from '../extensions/i18n/assets/LanguageData'

import { director } from 'cc';
// 默认的语言类型
export let _language = 'zh';
export let ready: boolean = false;

// 初始化语言类型,比如zh,en等
export function init(language: string) {
  ready = true;
  _language = language;
}

// 获取内容
export function t(key: string) {
  const win: any = window;
  if (!win.languages) {
    return key;
  }
  const searcher = key.split('.');
	// 根据语言类型获取不同的内容数据
  let data = win.languages[_language];
  // 遍历获取到对应key的内容
  for (let i = 0; i < searcher.length; i++) {
    data = data[searcher[i]];
    if (!data) {
      return '';
    }
  }
  return data || '';
}

// 更新场景渲染器
export function updateSceneRenderers() { 
  const rootNodes = director.getScene()!.children;
  // walk all nodes with localize label and update
  const allLocalizedLabels: any[] = [];
  // 遍历所有节点获取LocalizedLabel组件
  for (let i = 0; i < rootNodes.length; ++i) {
    let labels = rootNodes[i].getComponentsInChildren('LocalizedLabel');
    Array.prototype.push.apply(allLocalizedLabels, labels);
  }
  // 更新内容显示
  for (let i = 0; i < allLocalizedLabels.length; ++i) {
    let label = allLocalizedLabels[i];
    if(!label.node.active)continue;
    label.updateLabel();
  }
  // 遍历所有节点获取LocalizedSprite组件,对图片进行更新
  const allLocalizedSprites: any[] = [];
  for (let i = 0; i < rootNodes.length; ++i) {
    let sprites = rootNodes[i].getComponentsInChildren('LocalizedSprite');
    Array.prototype.push.apply(allLocalizedSprites, sprites);
  }
  for (let i = 0; i < allLocalizedSprites.length; ++i) {
    let sprite = allLocalizedSprites[i];
    if(!sprite.node.active)continue;
    sprite.updateSprite();
  }
}

图片的更新方法:updateSprite

// from '../extensions/i18n/assets/LocalizedSprite'

updateSprite () {
  for (let i = 0; i < this.spriteList.length; i++) {
    const item = this.spriteList[i];
    if (item.language === i18n._language) {
      this.sprite.spriteFrame = item.spriteFrame;
      break;
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/843000.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

P1194 买礼物(最小生成树)(内附封面)

买礼物 题目描述 又到了一年一度的明明生日了&#xff0c;明明想要买 B B B 样东西&#xff0c;巧的是&#xff0c;这 B B B 样东西价格都是 A A A 元。 但是&#xff0c;商店老板说最近有促销活动&#xff0c;也就是&#xff1a; 如果你买了第 I I I 样东西&#xff0…

【逗老师的PMP学习笔记】6、项目的进度管理

目录 一、规划进度管理1、【关键输出 】进度管理计划 二、定义活动1、【关键工具】拆解2、【关键工具】滚动式规划3、【关键输出】活动清单和活动属性4、【关键输出】里程碑清单 三、排列活动顺序1、【关键工具】紧前关系绘图法2、【关键工具】提前量和滞后量3、【关键输出】项…

Linux 中使用 verdaccio 搭建私有npm 服务器

安装 Node Linux中安装Node 安装verdaccio npm i -g verdaccio安装完成 输入verdaccio,出现下面信息代表安装成功&#xff0c;同时输入verdaccio后verdaccio已经处于运行状态&#xff0c;当然这种启动时暂时的&#xff0c;我们需要通过pm2让verdaccio服务常驻 ygiZ2zec61wsg…

网络编程——深入理解TCP/IP协议——OSI模型和TCP/IP模型:构建网络通信的基石

TCP/IP协议— 一、简介 TCP/IP协议&#xff0c;即传输控制协议/互联网协议&#xff0c;是一组用于在计算机网络中实现通信的协议。它由两个主要的协议组成&#xff1a;TCP&#xff08;传输控制协议&#xff09;和IP&#xff08;互联网协议&#xff09;。TCP负责确保数据的可靠…

【Linux取经路】冯诺依曼结构体系与操作系统的碰撞

文章目录 一、冯诺依曼体系结构1.1 硬件介绍1.2 内存的重要性 二、操作系统2.1 设计操作系统的目的2.2 操作系统是如何进行管理的&#xff1f; 一、冯诺依曼体系结构 我们现在常见的计算机&#xff0c;如笔记本&#xff0c;以及我们不常见的计算机&#xff0c;如服务器&#x…

Pycharm连接服务器

前提&#xff1a;必须为pycharm专业版才能连接到服务器 以下为pycharm2023专业版 一、连接 系统环境 虚拟环境&#xff08;前提&#xff1a;已安装anaconda&#xff09; (1) anaconda环境 (2) 自己创建的虚拟环境 这里为envs下的spotr 二、查看连接情况 选择自动上传

Docker 发布一个springboot项目

文章目录 1、新建SpringBootDemo项目并打包2、使用Dockerfile打包&#xff08;基础用法&#xff09;进一步maven源码打包法 3、更进一步&#xff08;maven插件打包&#xff09;docker-maven-pluginspring-boot-maven-plugin前提条件本地环境配置项目环境配置maven插件打包运行校…

一文让你了解网络安全和云安全的区别与联系

相信大家对于网络安全和云安全的关系不是很了解&#xff0c;今天小编就和大家来一起聊聊网络安全和云安全的区别与联系&#xff0c;仅供参考哦&#xff01; 网络安全和云安全的区别 1、两者定义不同。网络安全通常指计算机网络的安全&#xff0c;实际上也可以指计算机通信网络…

同源策略简单解释

浏览器同源策略 什么时同源策略 协议、域名(IP)、端口相同即为同源。浏览器的同源策略是一种约定&#xff0c;是浏览器最核心也是最基本的安全功能&#xff0c;如果浏览器少了同源策略&#xff0c;则浏览器的正常功能可能都会受到影响。 http://192.168.200.131/user/1 https…

全景图!最近20年,自然语言处理领域的发展

夕小瑶科技说 原创 作者 | 小戏、Python 最近这几年&#xff0c;大家一起共同经历了 NLP&#xff08;写一下全称&#xff0c;Natural Language Processing&#xff09; 这一领域井喷式的发展&#xff0c;从 Word2Vec 到大量使用 RNN、LSTM&#xff0c;从 seq2seq 再到 Attenti…

【产品经理】高阶产品如何提出有效解决方案?(1方法论+2案例+1清单)

每一件事情总有它的解决方案&#xff0c;在工作中亦是如此&#xff0c;而有效的解决方案&#xff0c;一定是具有系统性的。 有效的解决方案&#xff0c;一定是系统性的解决方案。 什么是系统性解决方案&#xff1f; 从系统结构&#xff08;或连接关系&#xff09;入手&#x…

生成2×2 或3*3 混淆矩阵(confusion matrix)的python代码

该代码可以生成22的混淆矩阵。每个矩阵对应的数值可以自行改变。 代码如下&#xff1a; import numpy as np import matplotlib.pyplot as plt# 随机生成值 import numpy as np import matplotlib.pyplot as plt# 创建一个2x2的二分类数据矩阵。这里可以手动改变值 data np…

拨开迷雾:利用全链路消息跟踪揭示系统奥秘

在分布式系统&#xff0c;一次外部请求往往需要内部多个模块&#xff0c;多个中间件&#xff0c;多台机器的相互调用才能完成。在这一系列的调用中&#xff0c;可能有些是串行的&#xff0c;而有些是并行的&#xff0c;排查定位非常困难。 全链路消息分析及全链路消息跟踪可以帮…

C# 简单模拟 程序内部 消息订阅发布功能

文章目录 前言模拟消息订阅发布使用注意事项 前言 我想做个简单的消息发布订阅功能&#xff0c;但是发现好像没有现成的工具类。要么就是Mqtt这种消息订阅发布。但是我只想程序内部进行消息订阅发布&#xff0c;进行程序的解耦。那没办法了&#xff0c;只能自己上了 模拟消息…

yolo-v5学习(使用yolo-v5进行安全帽检测错误记录)

常见错误 跑YOLOv5遇到的问题_runtimeerror: a view of a leaf variable that requi_Pysonmi的博客-CSDN博客 python train.py --img 640 --batch 16 --epochs 10 --data ./data/custom_data.yaml --cfg ./models/custom_yolov5.yaml --weights ./weights/yolov5s.pt 1、梯度…

实例032 动画显示窗体

实例说明 当用户启动程序后&#xff0c;普通的程序窗口都是瞬间显示到屏幕上&#xff0c;这样未免有些生硬。如果窗口能够慢慢的展现在用户面前&#xff0c;将会是什么样的效果&#xff1f;本例设计的是一个动画显示的窗体&#xff0c;该程序运行后&#xff0c;窗体是慢慢的以…

小黑子—JavaWeb:第六章 - Filter、Listener、AJAX与JSON

JavaWeb入门6.0 1. Filter1.1 Filter快速入门1.2 Filter执行流程1.3 Filter拦截路径配置1.4 Filter过滤器链1.5 案例登录验证 2. Listener2.1 ServletContextListener使用 3. AJAX3.1 AJAX 快速入门3.2 案例 验证用户名是否存在3.3 Axios 异步框架3.3.1 Axios 快速入门3.3.2 Ax…

自动驾驶新方法登Nature封面:让黑夜如白昼般清晰,浙大博士一作

摘要&#xff1a; 通过克服传统解决方案中的“重影”问题&#xff0c;这种方法在基准测试中一显巨大优势&#xff0c;不仅能像白天一样看清环境的纹理和深度&#xff0c;还能感知到RGB、热视觉以外的各种物理信息&#xff0c;可谓相当利好机器感知尤其是自动驾驶行业。 利用AI…

Flink多流处理之connect拼接流

Flink中的拼接流connect的使用其实非常简单,就是leftStream.connect(rightStream)的方式,但是有一点我们需要清楚,使用connect后并不是将两个流给串联起来了,而是将左流和右流建立一个联系,作为一个大的流,并且这个大的流可以使用相同的逻辑处理leftStream和rightStream,也可以…

【Leetcode】(自食用)删除链表中倒数第k个结点

step by step. 题目&#xff1a; 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&a…