热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CocosCreator中的多语言支持实现

在项目需要国际化处理时,即支持多种语言切换的功能,通常有两种方案:单个包和多个包。本文将重点讨论单个包的实现方法。

在项目需要国际化处理时,即支持多种语言切换的功能,通常有两种方案:

单个包

优点:

1. 可以动态切换语言(需要代码支持)

2. 只有一个版本,便于维护

缺点:

1. 安装包较大

多个包

优点:

1. 安装包较小

2. 可以对不同语言进行深度本地化(如功能差异)

缺点:

1. 需要多次提交审核

2. 多个版本的维护成本较高

下面我们重点讨论单个包的实现方法

由于 CocosCreator 内置的 i18n 功能可能不够灵活,因此我们需要自定义一个多语言处理系统。具体实现需要以下几个文件:

1. LanguageMgr.ts

2. LanguageSprite.ts

3. LanguageLabel.ts

4. language.json

以下是各文件的具体实现:

LanguageMgr.ts:

/*
多语言管理类,主要功能是加载多语言的图片和文字
*/
import { EventMgr } from "./EventMgr";
import { GlobalEvent } from "../model/EventType";
import { config } from "./config";
import { CallNative } from "./CallNative";
import { LanguageEnum } from "./Enum";

export class LanguageMgr {
    static languageJson = null;
    static kind = "EN";

    /**
     * 加载多语言json
     */
    static initLanguageJson() {
        this.languageJson = config.getOneConfig("language");
    }

    static init() {
        this.initLanguageJson();
        let kind = "EN";
        if (cc.sys.localStorage.getItem("lanAndCountry")) {
            kind = cc.sys.localStorage.getItem("lanAndCountry");
        } else {
            let lanAndCountry = CallNative.getLanguage();
            if (lanAndCountry.substr(0, 2) === "zh") {
                kind = LanguageEnum.tc;
            } else {
                kind = LanguageEnum.en;
            }
        }
        this.setKind(kind);
    }

    /**
     * 设置语言类型
     * @param kind 
     */
    static setKind(kind: string) {
        this.kind = kind;
    }

    /**
     * 获取当前语言类型
     * @param kind
     */
    static getKind() {
        return this.kind;
    }

    /**
     * 修改语言
     * @param kind 
     */
    static changeLanguage = function (kind: string) {
        if (this.kind !== kind) {
            this.setKind(kind);
            cc.sys.localStorage.setItem("lanAndCountry", kind);
            EventMgr.sendNormalEvent(GlobalEvent.CHANGE_LANGUAGE);
        }
    }

    /**
     * 获取语言包的key
     * @param text 
     * @param param 
     */
    static getText = function (text: string, param?: { "$param1": string | number }) {
        if (this.languageJson && this.languageJson[text]) {
            let str: string = this.languageJson[text][this.kind] || "";
            if (param) {
                if (param["$param1"] !== undefined) str = str.replace("$param1", param["$param1"].toString());
            }
            return str;
        } else if (text === "") {
            return "";
        } else {
            console.log("文本 " + text + " 没有多语言");
            return text;
        }
    }
}

LanguageSprite.ts:

import { LanguageMgr } from "../common/LanguageMgr";
import { GlobalEvent } from "../model/EventType";

const { ccclass, property, menu, requireComponent, disallowMultiple } = cc._decorator;

/**
 * 多语言的图片初始化
 */
@ccclass
@menu("多语言/sprite")
@requireComponent(cc.Sprite)
@disallowMultiple
export default class LanguageSprite extends cc.Component {
    @property(cc.SpriteFrame)
    en: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    sc: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    tc: cc.SpriteFrame = null;

    start() {
        cc.director.on(GlobalEvent.CHANGE_LANGUAGE, this.changeLanguage, this);
        this.changeLanguage();
    }

    /**
     * 监听切换语言事件
     */
    changeLanguage() {
        if (LanguageMgr.getKind() === "EN") {
            this.getComponent(cc.Sprite).spriteFrame = this.en;
        } else if (LanguageMgr.getKind() === "TC") {
            this.getComponent(cc.Sprite).spriteFrame = this.tc;
        } else {
            if (this.sc) {
                this.getComponent(cc.Sprite).spriteFrame = this.sc;
            } else {
                this.getComponent(cc.Sprite).spriteFrame = this.tc;
            }
        }
    }
}

LanguageLabel.ts:

import { GlobalEvent } from "../model/EventType";
import { LanguageMgr } from "../common/LanguageMgr";

const { ccclass, property, menu, requireComponent, disallowMultiple } = cc._decorator;

@ccclass
@menu("多语言/label")
@requireComponent(cc.Label)
@disallowMultiple
export default class LanguageLabel extends cc.Component {
    // LIFE-CYCLE CALLBACKS:

    @property
    prefix: string = "";

    @property
    suffix: string = "";

    @property
    text: string = "";

    start() {
        cc.director.on(GlobalEvent.CHANGE_LANGUAGE, this.changeLanguage, this);
        this.changeLanguage();
    }

    /**
     * 监听切换语言事件
     */
    changeLanguage() {
        var label = this.getComponent(cc.Label);
        if (label) {
            label.string = this.prefix + LanguageMgr.getText(this.text) + this.suffix;
        } else {
            console.log(this.node.name + " 挂载的节点没有label组件!");
        }
    }
}

language.json:

{
    "TEST_VERSION": {
        "EN": "Test Version",
        "TC": "測試版本",
        "SC": "测试版本"
    },
    "SERVER_IS_DISCONNTECTED_LOGIN_IN_AGAIN": {
        "EN": "The Server is Disconnected, Please Log In Again!",
        "TC": "伺服器已斷開鏈接,請重新登錄!",
        "SC": "服务器已断开连接,请重新登录!"
    },
    "DAILY_TASK": {
        "EN": "Daily Quest",
        "TC": "每日任務!",
        "SC": "每日任务!"
    },
    "OCCUPIED": {
        "EN": "Occupied",
        "TC": "使用中",
        "SC": "使用中"
    }
}

各个脚本的主要用法:

例如,LanguageMgr.getText("TEST_VERSION"); 当文本是动态变化时,需要使用 LanguageMgr.getText 方法。

如果是静态文本显示,则将 LanguageLabel 组件挂载到相应节点。

LanguageSprite 的使用方式与 LanguageLabel 类似。


推荐阅读
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 本文详细记录了在基于Debian的Deepin 20操作系统上安装MySQL 5.7的具体步骤,包括软件包的选择、依赖项的处理及远程访问权限的配置。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • 本文介绍了如何在C#中启动一个应用程序,并通过枚举窗口来获取其主窗口句柄。当使用Process类启动程序时,我们通常只能获得进程的句柄,而主窗口句柄可能为0。因此,我们需要使用API函数和回调机制来准确获取主窗口句柄。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
author-avatar
采蘑菇的小熙熙_395
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有