import { ImageAsset, resources, SpriteFrame, Texture2D } from 'cc'; import { Direction } from '../core/Define'; import { ensureSpriteFrameSize } from '../visual/EntityDisplayRefs'; import { ensureResourcesBundle } from '../core/ResourcesBundle'; import { resolvePlayerTexturePaths, EntityVisualOptions } from '../visual/EntityTextureResolver'; import { VisualAssets } from '../visual/VisualAssets'; import { getThemeHudIconCandidates, getThemePortraitPath, ThemeHudIconKey, } from '../theme/ThemeRegistry'; export type UIIconKey = ThemeHudIconKey; const frameCache = new Map(); function loadSpriteAt(path: string): Promise { const cached = frameCache.get(path); if (cached) return Promise.resolve(cached); return ensureResourcesBundle().then(() => new Promise((resolve) => { resources.load(`${path}/spriteFrame`, SpriteFrame, (err, sf) => { if (!err && sf) { frameCache.set(path, sf); resolve(sf); return; } resources.load(path, SpriteFrame, (err2, sf2) => { if (!err2 && sf2) { frameCache.set(path, sf2); resolve(sf2); return; } resources.load(path, ImageAsset, (err3, img) => { if (!err3 && img) { const tex = new Texture2D(); tex.image = img; const frame = new SpriteFrame(); frame.texture = tex; ensureSpriteFrameSize(frame, img.width, img.height); frameCache.set(path, frame); resolve(frame); return; } resolve(null); }); }); }); })); } export function getUIIconPath(uiStyle: string | undefined, icon: UIIconKey): string { const paths = getThemeHudIconCandidates(uiStyle, icon); if (!paths.length) throw new Error(`[UIStyleAssets] 缺少图标 ${icon}`); return paths[0]; } export async function loadUIIcon( uiStyle: string | undefined, icon: UIIconKey, ): Promise { for (const path of getThemeHudIconCandidates(uiStyle, icon)) { const sf = await loadSpriteAt(path); if (sf) return sf; } console.warn(`[UIStyleAssets] 贴图加载失败: ${icon} (${uiStyle ?? 'silu'})`); return null; } export function clearUIIconCache() { frameCache.clear(); } /** 地图左上角角色肖像(优先 entities.portrait,否则 playerFront) */ export async function loadThemeCharacterPortrait( options: EntityVisualOptions = {}, ): Promise { const theme = options.theme; const portrait = getThemePortraitPath(theme); if (portrait) { const sf = await VisualAssets.loadTexturePath(portrait); if (sf) return sf; } for (const path of resolvePlayerTexturePaths(Direction.South, options)) { const sf = await VisualAssets.loadTexturePath(path); if (sf) return sf; } console.warn(`[UIStyleAssets] 角色肖像加载失败 (${theme ?? 'silu'})`); return null; }