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 = new Map(); spineCache: Map = new Map(); languageData: Record = {}; 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 { 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 { 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((resolve) => { resources.load(path, SpriteFrame, (err, spriteFrame) => { if (!err && spriteFrame) { this.spriteFrameCache.set(cacheKey, spriteFrame); } resolve(); }); }); } } } private async preloadSpriteFrameAltas(): Promise { 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((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 { 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((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(); // }, // };