多语言模块
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
import { _decorator, Component, Label, Node } from "cc";
|
||||
import LanguageUtils, { LanguageType } from "./LanguageUtils";
|
||||
|
||||
const { ccclass, property, requireComponent } = _decorator;
|
||||
|
||||
@ccclass("LanguageLabel")
|
||||
@requireComponent(Label)
|
||||
export class LanguageLabel extends Component {
|
||||
@property({
|
||||
displayName: "Language Key",
|
||||
tooltip: "多语言配置表中的key值",
|
||||
})
|
||||
private languageKey: string = "";
|
||||
|
||||
@property({
|
||||
displayName: "Default Text",
|
||||
tooltip: "如果找不到对应的翻译时显示的默认文本",
|
||||
})
|
||||
private defaultText: string = "";
|
||||
|
||||
@property({
|
||||
displayName: "Auto Update",
|
||||
tooltip: "是否自动监听语言变化并更新",
|
||||
})
|
||||
private autoUpdate: boolean = true;
|
||||
|
||||
private label: Label = null;
|
||||
private params: { [key: string]: any } = null;
|
||||
|
||||
onLoad() {
|
||||
this.label = this.getComponent(Label);
|
||||
if (!this.label) {
|
||||
console.error("LanguageLabel: Label component not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateText();
|
||||
|
||||
if (this.autoUpdate) {
|
||||
LanguageUtils.onLanguageChanged(this.onLanguageChanged, this);
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
if (this.autoUpdate) {
|
||||
LanguageUtils.offLanguageChanged(this.onLanguageChanged, this);
|
||||
}
|
||||
}
|
||||
|
||||
onEnable() {
|
||||
this.updateText();
|
||||
}
|
||||
|
||||
private onLanguageChanged(language: LanguageType) {
|
||||
this.updateText();
|
||||
}
|
||||
|
||||
private updateText() {
|
||||
if (!this.label || !this.languageKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
let text: string;
|
||||
if (this.params && Object.keys(this.params).length > 0) {
|
||||
text = LanguageUtils.getTextWithParams(
|
||||
this.languageKey,
|
||||
this.params,
|
||||
this.defaultText
|
||||
);
|
||||
} else {
|
||||
text = LanguageUtils.getText(this.languageKey, this.defaultText);
|
||||
}
|
||||
|
||||
this.label.string = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置语言key
|
||||
*/
|
||||
public setLanguageKey(key: string) {
|
||||
this.languageKey = key;
|
||||
this.updateText();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文本参数(用于替换文本中的占位符)
|
||||
* @param params 参数对象,如 {name: "玩家", score: 100}
|
||||
*/
|
||||
public setParams(params: { [key: string]: any }) {
|
||||
this.params = params;
|
||||
this.updateText();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加或更新单个参数
|
||||
*/
|
||||
public setParam(key: string, value: any) {
|
||||
if (!this.params) {
|
||||
this.params = {};
|
||||
}
|
||||
this.params[key] = value;
|
||||
this.updateText();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有参数
|
||||
*/
|
||||
public clearParams() {
|
||||
this.params = null;
|
||||
this.updateText();
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动刷新文本
|
||||
*/
|
||||
public refresh() {
|
||||
this.updateText();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的语言key
|
||||
*/
|
||||
public getLanguageKey(): string {
|
||||
return this.languageKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认文本
|
||||
*/
|
||||
public setDefaultText(text: string) {
|
||||
this.defaultText = text;
|
||||
this.updateText();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "d7e4f3a2-8b9c-4d2e-a1f6-3c5e9d7b8a4f",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
import { _decorator, sys } from "cc";
|
||||
import { Language } from "../../schema/schema";
|
||||
import ConfigManager from "../../chat18x/manager/ConfigManager";
|
||||
import { CommonConfig } from "../Config/CommonConfig";
|
||||
import li_EventManager from "./li_EventManager";
|
||||
import Utils from "./Utils";
|
||||
import { InnerMsgCode } from "../Config/InnerMsgCode";
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
export enum LanguageType {
|
||||
EN = "en", // 英文
|
||||
CN = "cn", // 中文
|
||||
HI = "hi", // 印地语
|
||||
FR = "fr", // 法语
|
||||
DE = "de", //德语
|
||||
}
|
||||
|
||||
export enum LanguageEvent {
|
||||
LANGUAGE_CHANGED = "LANGUAGE_CHANGED",
|
||||
}
|
||||
|
||||
@ccclass("LanguageUtils")
|
||||
export default class LanguageUtils {
|
||||
private static currentLanguage: LanguageType = LanguageType.EN;
|
||||
private static languageCache: Map<string, string> = new Map();
|
||||
private static isInitialized: boolean = false;
|
||||
|
||||
public static get CurrentLanguage(): LanguageType {
|
||||
if (!this.isInitialized) {
|
||||
this.init();
|
||||
}
|
||||
return this.currentLanguage;
|
||||
}
|
||||
|
||||
private static init() {
|
||||
if (this.isInitialized) return;
|
||||
this.isInitialized = true;
|
||||
this.loadLanguageSetting();
|
||||
}
|
||||
|
||||
private static loadLanguageSetting() {
|
||||
const savedLanguage = sys.localStorage.getItem(
|
||||
CommonConfig.StorageConfig.LANGUAGE_SETTING
|
||||
);
|
||||
if (
|
||||
savedLanguage &&
|
||||
Object.values(LanguageType).includes(savedLanguage as LanguageType)
|
||||
) {
|
||||
this.currentLanguage = savedLanguage as LanguageType;
|
||||
} else {
|
||||
this.detectSystemLanguage();
|
||||
}
|
||||
console.log(
|
||||
"LanguageUtils initialized with language:",
|
||||
this.currentLanguage
|
||||
);
|
||||
}
|
||||
|
||||
private static detectSystemLanguage() {
|
||||
const systemLanguage = sys.language;
|
||||
if (systemLanguage.startsWith("zh")) {
|
||||
this.currentLanguage = LanguageType.CN;
|
||||
} else if (systemLanguage.startsWith("hi")) {
|
||||
this.currentLanguage = LanguageType.HI;
|
||||
} else if (systemLanguage.startsWith("fr")) {
|
||||
this.currentLanguage = LanguageType.FR;
|
||||
} else if (systemLanguage.startsWith("de")) {
|
||||
this.currentLanguage = LanguageType.DE;
|
||||
} else {
|
||||
this.currentLanguage = LanguageType.EN;
|
||||
}
|
||||
}
|
||||
|
||||
public static setLanguage(language: LanguageType): void {
|
||||
if (!this.isInitialized) {
|
||||
this.init();
|
||||
}
|
||||
|
||||
if (this.currentLanguage === language) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentLanguage = language;
|
||||
this.languageCache.clear();
|
||||
sys.localStorage.setItem(
|
||||
CommonConfig.StorageConfig.LANGUAGE_SETTING,
|
||||
language
|
||||
);
|
||||
|
||||
Utils.sendInnerMsg(InnerMsgCode.LanguageChange, language);
|
||||
console.log("Language changed to:", language);
|
||||
}
|
||||
|
||||
public static getText(key: string, defaultText: string = ""): string {
|
||||
if (!this.isInitialized) {
|
||||
this.init();
|
||||
}
|
||||
|
||||
if (!key) {
|
||||
return defaultText;
|
||||
}
|
||||
|
||||
if (this.languageCache.has(key)) {
|
||||
return this.languageCache.get(key);
|
||||
}
|
||||
|
||||
if (!ConfigManager.tables || !ConfigManager.tables.TbLanguage) {
|
||||
console.warn("Language table not loaded yet");
|
||||
return defaultText || key;
|
||||
}
|
||||
|
||||
const languageData = ConfigManager.tables.TbLanguage.get(key);
|
||||
if (!languageData) {
|
||||
console.warn(`Language key not found: ${key}`);
|
||||
return defaultText || key;
|
||||
}
|
||||
|
||||
let text: string = "";
|
||||
switch (this.currentLanguage) {
|
||||
case LanguageType.EN:
|
||||
text = languageData.languageEn;
|
||||
break;
|
||||
case LanguageType.CN:
|
||||
text = languageData.languageCn;
|
||||
break;
|
||||
case LanguageType.HI:
|
||||
text = languageData.languageHi;
|
||||
break;
|
||||
case LanguageType.FR:
|
||||
text = languageData.languageFr;
|
||||
break;
|
||||
case LanguageType.DE:
|
||||
text = languageData.languageDe;
|
||||
break;
|
||||
default:
|
||||
text = languageData.languageEn;
|
||||
}
|
||||
|
||||
if (!text || text.length === 0) {
|
||||
text = languageData.languageEn || defaultText || key;
|
||||
}
|
||||
|
||||
this.languageCache.set(key, text);
|
||||
return text;
|
||||
}
|
||||
|
||||
public static getTextWithParams(
|
||||
key: string,
|
||||
params: { [key: string]: any },
|
||||
defaultText: string = ""
|
||||
): string {
|
||||
let text = this.getText(key, defaultText);
|
||||
|
||||
for (let paramKey in params) {
|
||||
const regex = new RegExp(`{${paramKey}}`, "g");
|
||||
text = text.replace(regex, params[paramKey].toString());
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public static getAvailableLanguages(): LanguageType[] {
|
||||
return Object.values(LanguageType);
|
||||
}
|
||||
|
||||
public static getLanguageDisplayName(language: LanguageType): string {
|
||||
switch (language) {
|
||||
case LanguageType.EN:
|
||||
return "English";
|
||||
case LanguageType.CN:
|
||||
return "中文";
|
||||
case LanguageType.HI:
|
||||
return "हिंदी";
|
||||
case LanguageType.FR:
|
||||
return "Français";
|
||||
case LanguageType.DE:
|
||||
return "Deutsch";
|
||||
default:
|
||||
return language;
|
||||
}
|
||||
}
|
||||
|
||||
public static clearCache(): void {
|
||||
this.languageCache.clear();
|
||||
}
|
||||
|
||||
public static onLanguageChanged(
|
||||
callback: (language: LanguageType) => void,
|
||||
target: any
|
||||
): void {
|
||||
Utils.addInnerEL(InnerMsgCode.LanguageChange, target, callback);
|
||||
}
|
||||
|
||||
public static offLanguageChanged(
|
||||
callback: (language: LanguageType) => void,
|
||||
target: any
|
||||
): void {
|
||||
Utils.removeInnerEL(InnerMsgCode.LanguageChange, target, callback);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "c8b5e7a2-4f3d-4e8b-9c2a-1d6f5e8a7b9c",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ export namespace CommonConfig {
|
||||
DD_LEVELOPER = StorageConfigUtil.BaseData + 16, //进入关卡且首次进度>0时(或第一次操作)
|
||||
GUIDE_MAIN = StorageConfigUtil.BaseData + 17, //主界面引导是否完成
|
||||
GUIDE_TALK = StorageConfigUtil.BaseData + 18, //聊天界面引导是否完成
|
||||
LANGUAGE_SETTING = StorageConfigUtil.BaseData + 19, //语言设置
|
||||
|
||||
DOUYIN_SIDEBAR = StorageConfigUtil.Channel + 1, //抖音渠道侧边栏奖励是否领取
|
||||
}
|
||||
|
||||
@@ -26,4 +26,5 @@ export enum InnerMsgCode {
|
||||
|
||||
Chat_DialogRefresh,
|
||||
SimplePlayVide,
|
||||
LanguageChange,
|
||||
}
|
||||
Reference in New Issue
Block a user