import { _decorator, assetManager, resources, sp, SpriteFrame, AudioClip, Font } from 'cc'; const { ccclass } = _decorator; export type ResourceType = typeof SpriteFrame | typeof AudioClip | typeof sp.SkeletonData | typeof Font; interface ResourceGroup { path: string; type: ResourceType; weight: number; } @ccclass('ResourceLoader') export class ResourceLoader { private static _instance: ResourceLoader; // 获取单例实例 public static get instance(): ResourceLoader { if (!this._instance) { this._instance = new ResourceLoader(); } return this._instance; } private groups: ResourceGroup[] = []; private loadedResources: Map = new Map(); private constructor() {} /** 添加资源分组 */ addGroup(path: string, type: ResourceType, weight: number) { this.groups.push({ path, type, weight }); } /** 获取加载好的资源 */ getResource(name: string): T | undefined { return this.loadedResources.get(name) as T; } /** 释放所有资源(可选) */ releaseAll() { this.loadedResources.forEach((res) => { assetManager.releaseAsset(res); }); this.loadedResources.clear(); } /** 加载所有资源(带进度回调) */ async loadAll(onProgress?: (percent: number) => void, onComplete?: () => void) { const totalWeight = this.groups.reduce((sum, g) => sum + g.weight, 0); let accumulatedPercent = 0; for (const group of this.groups) { const groupWeight = group.weight; await new Promise((resolve, reject) => { resources.loadDir( group.path, group.type, (finished, total) => { const progress = finished / total; const overallPercent = accumulatedPercent + progress * (groupWeight / totalWeight) * 100; onProgress?.(overallPercent); }, (err, assets) => { if (err) { console.error(`加载失败: ${group.path}`, err); reject(err); return; } if (assets) { for (const asset of assets) { const name = asset.name; this.loadedResources.set(name, asset); } } accumulatedPercent += (groupWeight / totalWeight) * 100; resolve(); } ); }); } onProgress?.(100); onComplete?.(); } }