rp_11001/assets/Loading/scripts/manager/I18nManager.ts
2025-11-08 14:26:11 +08:00

218 lines
6.7 KiB
TypeScript

import { resources, JsonAsset, director, SpriteFrame, Sprite, Node, SpriteAtlas, sp } from 'cc';
import { LocalizedSprite } from '../i18n/LocalizedSprite';
export class I18nManager {
private static _instance: I18nManager = null;
spriteFrameCache: Map<string, SpriteFrame> = new Map();
spineCache: Map<string, sp.SkeletonData> = new Map();
languageData: Record<string, any> = {};
currentLanguage: string = 'en';
ready: boolean = false;
static get instance() {
if (this._instance) {
return this._instance;
}
this._instance = new I18nManager();
return this._instance;
}
private constructor() { }
/**
* 初始化语言管理器
* @param language 初始语言
*/
public async init(language: string = 'en', languageJson: JsonAsset): Promise<void> {
this.currentLanguage = language;
try {
this.languageData = languageJson.json;
// 预加载并缓存图片资源
await this.preloadSpriteFrames();
await this.preloadSpriteFrameAltas();
await this.preloadSpineAssets(); // 新增预加载 spine 资源
this.ready = true;
} catch (error) {
}
}
getIsReady() {
return this.ready;
}
/**
* 预加载并缓存图片资源
*/
private async preloadSpriteFrames(): Promise<void> {
const imageNames = [
'loadingBg',
'sysgift_completed',
'sysgift_continue',
'sysgift_fbs',
'sysgift_info_fbs',
'sysgift_received',
'sysgift_symbols',
'sysgift_total',
'sysgift_win',
];
for (const name of imageNames) {
const path = `i18nSprite/${this.currentLanguage}/${name}/spriteFrame`;
const cacheKey = `${this.currentLanguage}_${name}`;
if (!this.spriteFrameCache.has(cacheKey)) {
await new Promise<void>((resolve) => {
resources.load(path, SpriteFrame, (err, spriteFrame) => {
if (!err && spriteFrame) {
this.spriteFrameCache.set(cacheKey, spriteFrame);
}
resolve();
});
});
}
}
}
private async preloadSpriteFrameAltas(): Promise<void> {
const altasNames = [
`FreeSpinINOUT_${this.currentLanguage}`,
`BuyFeature_${this.currentLanguage}`,
`Others_${this.currentLanguage}`,
`SymbolsInfo_${this.currentLanguage}`,
]
for (const altasName of altasNames) {
const atlasPath = `i18nSprite/${this.currentLanguage}/${altasName}`;
// 加载图集并缓存其中的多个 SpriteFrame
await new Promise<void>((resolve) => {
resources.load(atlasPath, SpriteAtlas, (err, atlas) => {
if (!err && atlas) {
const spriteFrames = atlas.getSpriteFrames();
spriteFrames.forEach((frame, index) => {
let name = frame.name;
const cacheKey = `${this.currentLanguage}_${name}`;
this.spriteFrameCache.set(cacheKey, frame);
});
}
resolve();
});
});
}
}
// 添加预加载 Spine 资源的方法
private async preloadSpineAssets(): Promise<void> {
const spineNames = [
`WinWinWin_${this.currentLanguage}`,
];
for (const name of spineNames) {
const path = `i18nSprite/${this.currentLanguage}/${name}`;
const cacheKey = `${this.currentLanguage}_${name}`;
if (!this.spineCache.has(cacheKey)) {
await new Promise<void>((resolve) => {
resources.load(path, sp.SkeletonData, (err, spineData) => {
if (!err && spineData) {
this.spineCache.set(cacheKey, spineData);
}
resolve();
});
});
}
}
}
setSpriteFrame(node: Node, name: string) {
// 先尝试从缓存获取
const cacheKey = `${this.currentLanguage}_${name}`;
const cachedFrame = this.spriteFrameCache.get(cacheKey);
if (cachedFrame) {
const sprite = node.getComponent(Sprite);
if (sprite) {
sprite.spriteFrame = cachedFrame;
return;
}
}
// 如果缓存中没有,则使用原有逻辑
let spriteNode = node.getComponent(LocalizedSprite);
if (spriteNode) {
spriteNode.setSpriteName(name);
}
}
/**
* 设置当前语言
* @param language 语言代码
*/
public setLanguage(language: string): void {
if (this.languageData[language]) {
this.currentLanguage = language;
this.updateSceneRenderers();
}
}
/**
* 翻译文本
* @param key 翻译键
*/
public t(key: string): string {
const translation = this.languageData[this.currentLanguage]?.[key];
if (!translation) {
return key; // Return the key itself if translation is not found
}
return translation;
}
/**
* 更新场景中的本地化组件
*/
public updateSceneRenderers(): void {
if (!this.ready) {
console.warn('I18nManager is not ready.');
return;
}
let scene = director.getScene();
if (!scene || !scene.isValid) return;
const rootNodes = director.getScene()?.children || [];
const allLocalizedLabels: any[] = [];
const allLocalizedSprites: any[] = [];
rootNodes.forEach(node => {
allLocalizedLabels.push(...node.getComponentsInChildren('LocalizedLabel'));
allLocalizedSprites.push(...node.getComponentsInChildren('LocalizedSprite'));
});
allLocalizedLabels.forEach(label => {
if (label.node.active) {
label.updateLabel();
}
});
allLocalizedSprites.forEach(sprite => {
if (sprite.node.active) {
sprite.updateSprite();
}
});
}
}
// // 供插件查询当前语言使用
// const win = window as any;
// win._languageData = {
// get language() {
// return I18nManager.instance.currentLanguage;
// },
// init(lang: string) {
// I18nManager.instance.init(lang);
// },
// updateSceneRenderers() {
// I18nManager.instance.updateSceneRenderers();
// },
// };