mirror of
https://gitee.com/dgflash/oops-framework.git
synced 2026-06-18 19:52:10 +08:00
初次提交
This commit is contained in:
127
assets/script/core/gui/language/Language.ts
Normal file
127
assets/script/core/gui/language/Language.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { error, log, warn } from "cc";
|
||||
import { EventDispatcher } from "../../common/event/EventDispatcher";
|
||||
import { Logger } from "../../utils/Logger";
|
||||
import { LanguageLabel } from "./LanguageLabel";
|
||||
import LanguagePack from "./LanguagePack";
|
||||
|
||||
export enum LanguageEvent {
|
||||
/** 语种变化事件 */
|
||||
CHANGE = 'LanguageEvent.CHANGE',
|
||||
/** 语种资源释放事件 */
|
||||
RELEASE_RES = "LanguageEvent.RELEASE_RES"
|
||||
}
|
||||
const DEFAULT_LANGUAGE = "zh";
|
||||
|
||||
export class LanguageManager extends EventDispatcher {
|
||||
/** Label修改之前的回调 */
|
||||
public beforeChangeLabel: ((comp: LanguageLabel, content: string, dataID: string) => void) | null = null;
|
||||
|
||||
private _currentLang: string = ""; // 当前语言
|
||||
private _supportLanguages: Array<string> = ["zh", "en", "tr"]; // 支持的语言
|
||||
private _languagePack: LanguagePack = new LanguagePack(); // 语言包
|
||||
|
||||
/** 设置多语言系统支持哪些语种 */
|
||||
public set supportLanguages(supportLanguages: Array<string>) {
|
||||
this._supportLanguages = supportLanguages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前语种
|
||||
*/
|
||||
public get currentLanguage(): string {
|
||||
return this._currentLang;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支持的多语种数组
|
||||
*/
|
||||
public get languages(): string[] {
|
||||
return this._supportLanguages;
|
||||
}
|
||||
|
||||
public isExist(lang: string): boolean {
|
||||
return this.languages.indexOf(lang) > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下一个语种
|
||||
*/
|
||||
public getNextLang(): string {
|
||||
let supportLangs = this.languages;
|
||||
let index = supportLangs.indexOf(this._currentLang);
|
||||
let newLanguage = supportLangs[(index + 1) % supportLangs.length];
|
||||
return newLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变语种,会自动下载对应的语种,下载完成回调
|
||||
* @param language
|
||||
*/
|
||||
public setLanguage(language: string, callback: (success: boolean) => void) {
|
||||
if (!language) {
|
||||
language = DEFAULT_LANGUAGE;
|
||||
}
|
||||
language = language.toLowerCase();
|
||||
let index = this.languages.indexOf(language);
|
||||
if (index < 0) {
|
||||
warn("当前不支持该语种" + language + " 将自动切换到 zh 语种!");
|
||||
language = DEFAULT_LANGUAGE;
|
||||
}
|
||||
if (language === this._currentLang) {
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadLanguageAssets(language, (err: any, lang: string) => {
|
||||
if (err) {
|
||||
error("语言资源包下载失败", err);
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
Logger.logBusiness(`当前语言为【${language}】`);
|
||||
this._currentLang = language;
|
||||
this._languagePack.updateLanguage(language);
|
||||
this.dispatchEvent(LanguageEvent.CHANGE, lang);
|
||||
callback(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置多语言资源目录
|
||||
* @param langjsonPath 多语言json目录
|
||||
* @param langTexturePath 多语言图片目录
|
||||
*/
|
||||
public setAssetsPath(langjsonPath: string, langTexturePath: string) {
|
||||
this._languagePack.setAssetsPath(langjsonPath, langTexturePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据data获取对应语种的字符
|
||||
* @param labId
|
||||
* @param arr
|
||||
*/
|
||||
public getLangByID(labId: string): string {
|
||||
return this._languagePack.getLangByID(labId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载语言包素材资源
|
||||
* 包括语言json配置和语言纹理包
|
||||
* @param lang
|
||||
* @param callback
|
||||
*/
|
||||
public loadLanguageAssets(lang: string, callback: Function) {
|
||||
lang = lang.toLowerCase();
|
||||
return this._languagePack.loadLanguageAssets(lang, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放不需要的语言包资源
|
||||
* @param lang
|
||||
*/
|
||||
public releaseLanguageAssets(lang: string) {
|
||||
lang = lang.toLowerCase();
|
||||
this._languagePack.releaseLanguageAssets(lang);
|
||||
this.dispatchEvent(LanguageEvent.RELEASE_RES, lang);
|
||||
}
|
||||
}
|
||||
14
assets/script/core/gui/language/Language.ts.meta
Normal file
14
assets/script/core/gui/language/Language.ts.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "3757cc59-a8b6-4e6c-876f-3ff810e98ba3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"importAsPlugin": false,
|
||||
"moduleId": "project:///assets/script/core/gui/language/Language.js",
|
||||
"importerSettings": 4,
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
140
assets/script/core/gui/language/LanguageLabel.ts
Normal file
140
assets/script/core/gui/language/LanguageLabel.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
import { CCString, Component, error, Label, warn, _decorator } from "cc";
|
||||
import { EDITOR } from "cc/env";
|
||||
import { engine } from "../../Engine";
|
||||
|
||||
const { ccclass, property, menu } = _decorator;
|
||||
|
||||
@ccclass("LangLabelParamsItem")
|
||||
export class LangLabelParamsItem {
|
||||
@property
|
||||
key: string = "";
|
||||
@property
|
||||
value: string = "";
|
||||
}
|
||||
|
||||
@ccclass("LanguageLabel")
|
||||
@menu('ui/language/LanguageLabel')
|
||||
export class LanguageLabel extends Component {
|
||||
@property({
|
||||
type: LangLabelParamsItem,
|
||||
displayName: "params"
|
||||
})
|
||||
private _params: Array<LangLabelParamsItem> = [];
|
||||
|
||||
@property({
|
||||
type: LangLabelParamsItem,
|
||||
displayName: "params"
|
||||
})
|
||||
set params(value: Array<LangLabelParamsItem>) {
|
||||
this._params = value;
|
||||
if (!EDITOR) {
|
||||
this._needUpdate = true;
|
||||
}
|
||||
}
|
||||
get params(): Array<LangLabelParamsItem> {
|
||||
return this._params || [];
|
||||
}
|
||||
|
||||
@property({ serializable: true })
|
||||
private _dataID: string = "";
|
||||
@property({ type: CCString, serializable: true })
|
||||
get dataID(): string {
|
||||
return this._dataID || "";
|
||||
}
|
||||
set dataID(value: string) {
|
||||
this._dataID = value;
|
||||
if (!EDITOR) {
|
||||
this._needUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
get string(): string {
|
||||
let _string = engine.i18n.getLangByID(this._dataID);
|
||||
if (engine.i18n.beforeChangeLabel) {
|
||||
engine.i18n.beforeChangeLabel(this, _string, this._dataID);
|
||||
}
|
||||
if (_string && this._params.length > 0) {
|
||||
this._params.forEach((item: LangLabelParamsItem) => {
|
||||
_string = _string.replace(`%{${item.key}}`, item.value)
|
||||
})
|
||||
}
|
||||
if (!_string) {
|
||||
warn("[LanguageLabel] 未找到语言标识,使用dataID替换");
|
||||
_string = this._dataID;
|
||||
}
|
||||
return _string;
|
||||
}
|
||||
|
||||
set language(lang: string) {
|
||||
this._needUpdate = true;
|
||||
}
|
||||
|
||||
initFontSize: number = 0;
|
||||
|
||||
onLoad() {
|
||||
this._needUpdate = true;
|
||||
if (!this.getComponent(Label)) error(this.node.name, this._dataID);
|
||||
this.initFontSize = this.getComponent(Label)!.fontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认文本的系统字体名字
|
||||
*/
|
||||
public getLabelFont(lang: string): string {
|
||||
switch (lang) {
|
||||
case "zh":
|
||||
case "tr": {
|
||||
return "SimHei";
|
||||
}
|
||||
}
|
||||
return "Helvetica";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改多语言参数,采用惰性求值策略
|
||||
* @param key 对于i18n表里面的key值
|
||||
* @param value 替换的文本
|
||||
*/
|
||||
setVars(key: string, value: string) {
|
||||
let haskey = false;
|
||||
for (let i = 0; i < this._params.length; i++) {
|
||||
let element: LangLabelParamsItem = this._params[i];
|
||||
if (element.key === key) {
|
||||
element.value = value;
|
||||
haskey = true;
|
||||
}
|
||||
}
|
||||
if (!haskey) {
|
||||
let ii = new LangLabelParamsItem();
|
||||
ii.key = key;
|
||||
ii.value = value;
|
||||
this._params.push(ii);
|
||||
}
|
||||
this._needUpdate = true;
|
||||
}
|
||||
private _needUpdate: boolean = false;
|
||||
|
||||
update() {
|
||||
if (this._needUpdate) {
|
||||
this.updateLabel();
|
||||
this._needUpdate = false;
|
||||
}
|
||||
}
|
||||
updateLabel() {
|
||||
do {
|
||||
if (!this._dataID) {
|
||||
break;
|
||||
}
|
||||
|
||||
let spcomp = this.getComponent(Label);
|
||||
if (!spcomp) {
|
||||
warn("[LanguageLabel], 该节点没有cc.Label组件");
|
||||
break;
|
||||
}
|
||||
|
||||
spcomp.fontFamily = this.getLabelFont(engine.i18n.currentLanguage);
|
||||
spcomp.string = this.string;
|
||||
}
|
||||
while (false);
|
||||
}
|
||||
}
|
||||
14
assets/script/core/gui/language/LanguageLabel.ts.meta
Normal file
14
assets/script/core/gui/language/LanguageLabel.ts.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "110c8bc4-7793-443c-bfcd-f66786427697",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"importAsPlugin": false,
|
||||
"moduleId": "project:///assets/script/core/gui/language/LanguageLabel.js",
|
||||
"importerSettings": 4,
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
102
assets/script/core/gui/language/LanguagePack.ts
Normal file
102
assets/script/core/gui/language/LanguagePack.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { director, error, JsonAsset, resources, warn } from "cc";
|
||||
import { Logger } from "../../utils/Logger";
|
||||
import { resLoader } from "../../utils/ResLoader";
|
||||
import { LanguageLabel } from "./LanguageLabel";
|
||||
import { LanguageSprite } from "./LanguageSprite";
|
||||
|
||||
export default class LanguagePack {
|
||||
private _languageLabels: any = {};
|
||||
|
||||
// 默认资源文件目录
|
||||
private _langjsonPath: string = "lang_json";
|
||||
private _langTexturePath: string = "lang_texture";
|
||||
|
||||
/**
|
||||
* 设置多语言资源目录
|
||||
* @param langjsonPath 多语言json目录
|
||||
* @param langTexturePath 多语言图片目录
|
||||
*/
|
||||
public setAssetsPath(langjsonPath: string, langTexturePath: string) {
|
||||
if (langjsonPath) {
|
||||
this._langjsonPath = langjsonPath;
|
||||
}
|
||||
if (langTexturePath) {
|
||||
this._langTexturePath = langTexturePath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新语言文字
|
||||
* @param lang
|
||||
*/
|
||||
public updateLanguage(lang: string) {
|
||||
let lanjson = resLoader.get(`${this._langjsonPath}/${lang}`, JsonAsset);
|
||||
if (lanjson && lanjson.json) {
|
||||
this._languageLabels = lanjson.json;
|
||||
let rootNodes = director.getScene()!.children;
|
||||
for (let i = 0; i < rootNodes.length; ++i) {
|
||||
// 更新所有的LanguageLabel节点
|
||||
let languagelabels = rootNodes[i].getComponentsInChildren(LanguageLabel);
|
||||
for (let j = 0; j < languagelabels.length; j++) {
|
||||
languagelabels[j].language = lang;
|
||||
}
|
||||
// 更新所有的LanguageSprite节点
|
||||
let languagesprites = rootNodes[i].getComponentsInChildren(LanguageSprite);
|
||||
for (let j = 0; j < languagesprites.length; j++) {
|
||||
languagesprites[j].language = lang;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
warn("没有找到指定语言内容配置", lang);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据dataID,获取对应语言的字符
|
||||
* @param uuid
|
||||
*/
|
||||
public getLangByID(labId: string): string {
|
||||
return this._languageLabels[labId] || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对应语言包资源
|
||||
* @param lang 语言标识
|
||||
* @param callback 下载完成回调
|
||||
*/
|
||||
public loadLanguageAssets(lang: string, callback: Function) {
|
||||
let lang_texture_path = `${this._langTexturePath}/${lang}`;
|
||||
let lang_json_path = `${this._langjsonPath}/${lang}`;
|
||||
resLoader.loadDir(lang_texture_path, (err: any) => {
|
||||
if (err) {
|
||||
error(err);
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
Logger.logBusiness(lang_texture_path, "下载语言包 textures 资源");
|
||||
resLoader.load(lang_json_path, JsonAsset, (err) => {
|
||||
if (err) {
|
||||
error(err);
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
Logger.trace(lang_json_path, "下载语言包 json 资源");
|
||||
callback(err, lang);
|
||||
})
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 释放某个语言的语言包资源包括json
|
||||
* @param lang
|
||||
*/
|
||||
public releaseLanguageAssets(lang: string) {
|
||||
let langpath = `${this._langTexturePath}/${lang}`;
|
||||
resLoader.releaseDir(langpath);
|
||||
Logger.logBusiness(langpath, "释放语言图片资源");
|
||||
|
||||
let langjsonpath = `${this._langjsonPath}/${lang}`;
|
||||
resLoader.release(langjsonpath);
|
||||
Logger.logBusiness(langjsonpath, "释放语言文字资源");
|
||||
}
|
||||
}
|
||||
14
assets/script/core/gui/language/LanguagePack.ts.meta
Normal file
14
assets/script/core/gui/language/LanguagePack.ts.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "2ffebca3-e7dc-4873-8bf8-059b72f120e6",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"importAsPlugin": false,
|
||||
"moduleId": "project:///assets/script/core/gui/language/LanguagePack.js",
|
||||
"importerSettings": 4,
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
16
assets/script/core/gui/language/LanguagePointLabel.ts.meta
Normal file
16
assets/script/core/gui/language/LanguagePointLabel.ts.meta
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ver": "4.0.1",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "a1bd53a3-66a7-4477-8c18-9254dc5983bf",
|
||||
"files": [
|
||||
".js",
|
||||
".trans"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"importAsPlugin": false,
|
||||
"moduleId": "project:///assets/script/core/gui/language/LanguagePointLabel.js",
|
||||
"importerSettings": 3
|
||||
}
|
||||
}
|
||||
46
assets/script/core/gui/language/LanguageSprite.ts
Normal file
46
assets/script/core/gui/language/LanguageSprite.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Component, Size, Sprite, SpriteFrame, UITransform, _decorator } from "cc";
|
||||
import { engine } from "../../Engine";
|
||||
import { Logger } from "../../utils/Logger";
|
||||
import { resLoader } from "../../utils/ResLoader";
|
||||
|
||||
const { ccclass, property, menu } = _decorator;
|
||||
|
||||
@ccclass("LanguageSprite")
|
||||
@menu('ui/language/LanguageSprite')
|
||||
export class LanguageSprite extends Component {
|
||||
@property({
|
||||
tooltip: "资源路径(language/texture/内的相对路径)"
|
||||
})
|
||||
public path: string = "";
|
||||
|
||||
@property({
|
||||
tooltip: "是否设置为图片原始资源大小"
|
||||
})
|
||||
private isRawSize: boolean = true;
|
||||
|
||||
start() {
|
||||
this.language = engine.i18n.currentLanguage;
|
||||
}
|
||||
|
||||
set language(lang: string) {
|
||||
this.updateSprite(lang);
|
||||
}
|
||||
|
||||
updateSprite(lang: string) {
|
||||
let spcomp: Sprite = this.getComponent(Sprite)!;
|
||||
// 获取语言标记
|
||||
let path = `language/texture/${lang}/${this.path}/spriteFrame`;
|
||||
let res = resLoader.get(path, SpriteFrame);
|
||||
if (!res) {
|
||||
Logger.erroring("[LanguageSprite] 资源不存在 " + path);
|
||||
}
|
||||
spcomp.spriteFrame = res;
|
||||
|
||||
/** 修改节点为原始图片资源大小 */
|
||||
if (this.isRawSize) {
|
||||
//@ts-ignore
|
||||
let rawSize = res._originalSize as Size;
|
||||
spcomp.getComponent(UITransform)?.setContentSize(rawSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
assets/script/core/gui/language/LanguageSprite.ts.meta
Normal file
14
assets/script/core/gui/language/LanguageSprite.ts.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "11b9693f-4486-45e7-b2e8-7a1c7297a1ec",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"importAsPlugin": false,
|
||||
"moduleId": "project:///assets/script/core/gui/language/LanguageSprite.js",
|
||||
"importerSettings": 4,
|
||||
"simulateGlobals": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user