ResourceLoader.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { _decorator, assetManager, resources, sp, SpriteFrame, AudioClip, Font } from 'cc';
  2. const { ccclass } = _decorator;
  3. export type ResourceType = typeof SpriteFrame | typeof AudioClip | typeof sp.SkeletonData | typeof Font;
  4. interface ResourceGroup {
  5. path: string;
  6. type: ResourceType;
  7. weight: number;
  8. }
  9. @ccclass('ResourceLoader')
  10. export class ResourceLoader {
  11. private static _instance: ResourceLoader;
  12. // 获取单例实例
  13. public static get instance(): ResourceLoader {
  14. if (!this._instance) {
  15. this._instance = new ResourceLoader();
  16. }
  17. return this._instance;
  18. }
  19. private groups: ResourceGroup[] = [];
  20. private loadedResources: Map<string, any> = new Map();
  21. private constructor() {}
  22. /** 添加资源分组 */
  23. addGroup(path: string, type: ResourceType, weight: number) {
  24. this.groups.push({ path, type, weight });
  25. }
  26. /** 获取加载好的资源 */
  27. getResource<T>(name: string): T | undefined {
  28. return this.loadedResources.get(name) as T;
  29. }
  30. /** 释放所有资源(可选) */
  31. releaseAll() {
  32. this.loadedResources.forEach((res) => {
  33. assetManager.releaseAsset(res);
  34. });
  35. this.loadedResources.clear();
  36. }
  37. /** 加载所有资源(带进度回调) */
  38. async loadAll(onProgress?: (percent: number) => void, onComplete?: () => void) {
  39. const totalWeight = this.groups.reduce((sum, g) => sum + g.weight, 0);
  40. let accumulatedPercent = 0;
  41. for (const group of this.groups) {
  42. const groupWeight = group.weight;
  43. await new Promise<void>((resolve, reject) => {
  44. resources.loadDir(
  45. group.path,
  46. group.type,
  47. (finished, total) => {
  48. const progress = finished / total;
  49. const overallPercent = accumulatedPercent + progress * (groupWeight / totalWeight) * 100;
  50. onProgress?.(overallPercent);
  51. },
  52. (err, assets) => {
  53. if (err) {
  54. console.error(`加载失败: ${group.path}`, err);
  55. reject(err);
  56. return;
  57. }
  58. if (assets) {
  59. for (const asset of assets) {
  60. const name = asset.name;
  61. this.loadedResources.set(name, asset);
  62. }
  63. }
  64. accumulatedPercent += (groupWeight / totalWeight) * 100;
  65. resolve();
  66. }
  67. );
  68. });
  69. }
  70. onProgress?.(100);
  71. onComplete?.();
  72. }
  73. }