feat: add builder configuration file
feat: add cocos-service configuration file feat: add device configuration file feat: add engine configuration file feat: add information configuration file feat: add program configuration file feat: add project configuration file feat: add TypeScript configuration file
This commit is contained in:
281
assets/script/common/LoadTools.ts
Normal file
281
assets/script/common/LoadTools.ts
Normal file
@@ -0,0 +1,281 @@
|
||||
import { director, Node, instantiate, Prefab, Vec3, v3, SpriteFrame, Sprite, AssetManager, resources, assetManager, AudioClip, Material, Texture2D, Label } from "cc";
|
||||
import { ResModel } from "../model/ResModel";
|
||||
import { weiSan } from "./weiSanTools";
|
||||
import { EventManager, EventData } from "../manager/EventManager";
|
||||
import { PoolManager } from "../manager/PoolManager";
|
||||
|
||||
/** 加载资源相关工具类 */
|
||||
export class LoadTools {
|
||||
/** 单例模式 */
|
||||
private static _instance: LoadTools = new LoadTools();
|
||||
private constructor() { }
|
||||
public static get _ins() {
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载游戏场景
|
||||
* @param sceneName 加载场景的名字
|
||||
* @param callFunc 加载回调
|
||||
*/
|
||||
loadScene(sceneName: string, callFunc: any, isClear = true) {
|
||||
if (isClear) {
|
||||
ResModel._ins.clearResDic();
|
||||
}
|
||||
director.preloadScene(sceneName, () => {
|
||||
director.loadScene(sceneName, callFunc);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 加载resource 下的预制体 资源
|
||||
* @param url resource 下的资源路径
|
||||
* @param callBack 加载完成回调
|
||||
*/
|
||||
loadResPrefab(url: string, callBack?: any, parent?: Node, Pos?: Vec3) {
|
||||
this.loadResAny(url, Prefab, (prefab: Prefab) => {
|
||||
let clone = instantiate(prefab);
|
||||
if (parent) { parent.addChild(clone) };
|
||||
if (Pos) { clone.position = v3(Pos.x, Pos.y, 0) };
|
||||
if (callBack != null) {
|
||||
callBack(clone);
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 加载resource 下的图片资源并渲染到节点上
|
||||
* @param url resource 下的资源路径
|
||||
* @param callBack 加载完成回调
|
||||
*/
|
||||
loadResSpriteFrame(url: string, sprite: Node, parent?: Node, Pos?: Vec3, callBack?: any) {
|
||||
resources.load(url + "/spriteFrame", SpriteFrame, function (error: any, SpriteFrame: SpriteFrame) {
|
||||
if (error) {
|
||||
weiSan.error(error);
|
||||
} else {
|
||||
sprite.getComponent(Sprite).spriteFrame = SpriteFrame;
|
||||
if (parent) { parent.addChild(sprite) };
|
||||
if (Pos) { sprite.position = v3(Pos.x, Pos.y, 0) };
|
||||
if (callBack != null) {
|
||||
callBack(sprite);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 加载resource 下的游戏资源
|
||||
* @param url resource 下的资源路径
|
||||
* @param resType 加载资源的类型
|
||||
* @param callBack 加载完成回调
|
||||
*/
|
||||
loadResAny(url: string, resType: any, callBack?: any) {
|
||||
resources.load(url, resType, function (error: any, res: any) {
|
||||
if (error) {
|
||||
weiSan.error(error);
|
||||
} else {
|
||||
if (callBack != null) {
|
||||
callBack(res);
|
||||
}
|
||||
if (resType == Prefab) {
|
||||
ResModel._ins.PrefabDic.set(url, res);
|
||||
} else if (resType == SpriteFrame) {
|
||||
if (!ResModel._ins.SpriteFrameDic.has(url)) {
|
||||
ResModel._ins.SpriteFrameDic.set(url, res);
|
||||
}
|
||||
} else if (resType == AudioClip) {
|
||||
if (!ResModel._ins.AudioClipDic.has(url)) {
|
||||
ResModel._ins.AudioClipDic.set(url, res);
|
||||
}
|
||||
} else if (resType == Material) {
|
||||
if (!ResModel._ins.MaterialDic.has(url)) {
|
||||
ResModel._ins.MaterialDic.set(url, res);
|
||||
}
|
||||
} else if (resType == Texture2D) {
|
||||
if (!ResModel._ins.TextureDic.has(url)) {
|
||||
ResModel._ins.TextureDic.set(url, res);
|
||||
}
|
||||
} else if (resType === Prefab) {
|
||||
if (!ResModel._ins.PrefabDic.has(url)) {
|
||||
ResModel._ins.PrefabDic.set(url, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 加载bundle 场景 */
|
||||
loadBundleScene(bundleName: string, sceneName: string, onFinishBack?: () => void, isInScene: boolean = true) {
|
||||
assetManager.loadBundle(
|
||||
bundleName,
|
||||
(err: any, bundle: AssetManager.Bundle) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
else {
|
||||
if (!isInScene) { return; }
|
||||
bundle.loadScene(sceneName, (err, scene) => {
|
||||
if (onFinishBack) {
|
||||
onFinishBack();
|
||||
}
|
||||
director.runScene(scene);
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分帧加载预制体节点
|
||||
* @param prefabName 要加载的预制体名称
|
||||
* @param perFrameNum 每帧加载的数量
|
||||
* @param totalNum 总共需要加载的数量
|
||||
* @param usePool 是否使用对象池,默认为true
|
||||
* @param callBack 对每个创建的节点进行操作的回调函数
|
||||
* @returns Promise<Node[]> 返回所有创建的节点数组
|
||||
*/
|
||||
loadPrefabByFrame(prefabName: string, perFrameNum: number, totalNum: number, usePool: boolean = true, callBack?: (node: Node, index: number) => void): Promise<Node[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 参数验证
|
||||
if (!prefabName || prefabName.trim() === '') {
|
||||
const error = 'prefabName cannot be empty';
|
||||
weiSan.error(error);
|
||||
reject(new Error(error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (perFrameNum <= 0) {
|
||||
const error = 'perFrameNum must be greater than 0';
|
||||
weiSan.error(error);
|
||||
reject(new Error(error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (totalNum <= 0) {
|
||||
const error = 'totalNum must be greater than 0';
|
||||
weiSan.error(error);
|
||||
reject(new Error(error));
|
||||
return;
|
||||
}
|
||||
|
||||
// 触发加载开始事件
|
||||
EventManager.dispatchEvent(EventData.PREFAB_LOAD_START, {
|
||||
prefabName: prefabName,
|
||||
totalNum: totalNum,
|
||||
usePool: usePool
|
||||
});
|
||||
|
||||
// 创建节点的函数
|
||||
const createNodeFunction = (prefab?: Prefab): Node | null => {
|
||||
if (usePool) {
|
||||
// 使用对象池创建节点
|
||||
return PoolManager._ins.getNode(prefabName);
|
||||
} else {
|
||||
// 使用传统方式创建节点
|
||||
if (!prefab) {
|
||||
weiSan.error(`Prefab is required when not using pool: ${prefabName}`);
|
||||
return null;
|
||||
}
|
||||
return instantiate(prefab);
|
||||
}
|
||||
};
|
||||
|
||||
if (usePool) {
|
||||
// 使用对象池时,直接开始分帧创建
|
||||
this.startFrameBasedCreation(prefabName, perFrameNum, totalNum, usePool, callBack, createNodeFunction, resolve, reject);
|
||||
} else {
|
||||
// 不使用对象池时,先加载预制体资源
|
||||
this.loadResAny(prefabName, Prefab, (prefab: Prefab) => {
|
||||
if (!prefab) {
|
||||
const error = `Failed to load prefab: ${prefabName}`;
|
||||
weiSan.error(error);
|
||||
reject(new Error(error));
|
||||
return;
|
||||
}
|
||||
this.startFrameBasedCreation(prefabName, perFrameNum, totalNum, usePool, callBack, createNodeFunction, resolve, reject, prefab);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始分帧创建节点的核心逻辑
|
||||
*/
|
||||
private startFrameBasedCreation(
|
||||
prefabName: string,
|
||||
perFrameNum: number,
|
||||
totalNum: number,
|
||||
usePool: boolean,
|
||||
callBack: ((node: Node, index: number) => void) | undefined,
|
||||
createNodeFunction: (prefab?: Prefab) => Node | null,
|
||||
resolve: (value: Node[]) => void,
|
||||
reject: (reason?: any) => void,
|
||||
prefab?: Prefab
|
||||
) {
|
||||
// 开始分帧创建节点
|
||||
const createdNodes: Node[] = [];
|
||||
let currentCount = 0;
|
||||
|
||||
const createNodesPerFrame = () => {
|
||||
const remainingCount = totalNum - currentCount;
|
||||
const currentFrameCount = Math.min(perFrameNum, remainingCount);
|
||||
|
||||
// 创建当前帧的节点
|
||||
for (let i = 0; i < currentFrameCount; i++) {
|
||||
try {
|
||||
const node = createNodeFunction(prefab);
|
||||
if (!node) {
|
||||
const error = `Failed to create node: ${prefabName}`;
|
||||
weiSan.error(error);
|
||||
reject(new Error(error));
|
||||
return;
|
||||
}
|
||||
|
||||
createdNodes.push(node);
|
||||
|
||||
// 执行回调函数
|
||||
if (callBack) {
|
||||
try {
|
||||
callBack(node, currentCount);
|
||||
} catch (callbackError) {
|
||||
weiSan.warn(`Callback error for node ${currentCount}: ${callbackError}`);
|
||||
}
|
||||
}
|
||||
|
||||
currentCount++;
|
||||
} catch (error) {
|
||||
weiSan.error(`Error creating node instance: ${error}`);
|
||||
reject(new Error(`Error creating node instance: ${error}`));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 计算进度并触发进度事件
|
||||
const progress = (currentCount / totalNum) * 100;
|
||||
EventManager.dispatchEvent(EventData.PREFAB_LOAD_PROGRESS, {
|
||||
prefabName: prefabName,
|
||||
currentNum: currentCount,
|
||||
totalNum: totalNum,
|
||||
progress: progress
|
||||
});
|
||||
|
||||
// 检查是否完成
|
||||
if (currentCount >= totalNum) {
|
||||
// 触发完成事件
|
||||
EventManager.dispatchEvent(EventData.PREFAB_LOAD_COMPLETE, {
|
||||
prefabName: prefabName,
|
||||
totalNum: totalNum,
|
||||
nodes: createdNodes
|
||||
});
|
||||
|
||||
weiSan.log(`Successfully loaded ${totalNum} instances of prefab: ${prefabName}`);
|
||||
resolve(createdNodes);
|
||||
} else {
|
||||
// 继续下一帧,使用 setTimeout 来实现分帧
|
||||
setTimeout(() => {
|
||||
createNodesPerFrame();
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
// 开始第一帧的创建
|
||||
createNodesPerFrame();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user