123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- import { _decorator, Component, Label, Tween, tween, v3 } from "cc";
- import { Logger } from "./Logger";
- const { ccclass, property } = _decorator;
- /*初始化加载界面*/
- interface LoadingTask {
- progress: number;
- tips?: string;
- callback?: () => void | Promise<void>;
- }
- @ccclass("LoadingUI")
- export class LoadingUI extends Component {
- @property(Label)
- public progressLabel: Label = null!;
-
- @property(Label)
- public tipLabel: Label = null!;
-
- private _currentProgress = 0;
- private _isLoading = false;
- private _progressTween: Tween<any> | null = null;
- private _taskQueue: LoadingTask[] = [];
- private _currentTaskIndex = 0;
- /**
- * 开始加载流程
- * @param initialProgress 初始进度 (0-100)
- * @example 调用事例:
- * this.loadingUI.startLoading();
- //添加所有加载任务
- this.loadingUI.addTask(10, '资源加载中...', () => {
- PlayerData.ins().initialize();
- PlatformSystem.initialize();
- SettingData.ins().initialize();
- });
- this.loadingUI.addTask(30, '加载音乐资源...', async () => {
- await AudioManager.initialize();
- });
- this.loadingUI.addTask(40, '加载关卡数据...', async () => {
- await LevelsResData.ins().initialize();
- await LevelsResData.instance.preLoadAllMap();
- });
- this.loadingUI.addTask(20, '预加载场景...', async () => {
- await SceneManager.initialize();
- });
- //执行所有任务完成后会自动调用finishLoading()
- await this.loadingUI.executeTasks();
- */
- public startLoading(initialProgress: number = 0) {
- if (this._isLoading) {
- Logger.warn("Loading is already in progress");
- return;
- }
- this.node.active = true;
- this._isLoading = true;
- this._currentProgress = initialProgress;
- this._updateProgressDisplay(this._currentProgress);
- }
- /**
- * 添加一个加载任务
- * @param progress 该任务增加的进度值 (0-100)
- * @param tips 提示文本
- * @param callback 任务回调函数,可以是异步的
- */
- public addTask(progress: number, tips?: string, callback?: () => void | Promise<void>) {
- this._taskQueue.push({ progress, tips, callback });
- }
- /**
- * 执行所有加载任务
- */
- public async executeTasks() {
- if (!this._isLoading) {
- Logger.warn("Loading has not started yet");
- return;
- }
- for (this._currentTaskIndex = 0; this._currentTaskIndex < this._taskQueue.length; this._currentTaskIndex++) {
- const task = this._taskQueue[this._currentTaskIndex];
- //更新提示文本
- if (task.tips) {
- this.tipLabel.string = task.tips;
- }
- //执行任务回调
- if (task.callback) {
- try {
- const result = task.callback();
- if (result instanceof Promise) {
- await result;
- }
- } catch (error) {
- Logger.error("Loading task failed:", error);
- }
- }
- //更新进度
- await this._updateProgress(this._currentProgress + task.progress);
- }
- //所有任务完成后自动完成加载
- await this.finishLoading();
- }
- /**
- * 直接设置进度(带动画)
- * @param targetProgress 目标进度 (0-100)
- * @param duration 动画持续时间 (秒)
- */
- public async setProgress(targetProgress: number, duration: number = 0.3) {
- if(!this._isLoading) {
- Logger.warn("Loading has not started yet");
- return;
- }
- await this._updateProgress(targetProgress, duration);
- }
- /**
- * 完成加载(自动跳转到100%)
- */
- public async finishLoading(isHide: boolean = false) {
- if(!this._isLoading) {
- Logger.warn("Loading has not started yet");
- return;
- }
- await this._updateProgress(100, 0.5);
- this._isLoading = false;
- //延迟隐藏
- await new Promise(resolve => setTimeout(resolve, 500));
- if(isHide){this.node.active = false;}
- //重置状态
- this._reset();
- }
- private _reset() {
- this._currentProgress = 0;
- this._taskQueue = [];
- this._currentTaskIndex = 0;
- if (this._progressTween) {
- this._progressTween.stop();
- this._progressTween = null;
- }
- }
- private async _updateProgress(targetProgress: number, duration: number = 0.3) {
- //确保进度在0-100范围内
- targetProgress = Math.min(100, Math.max(0, targetProgress));
- // 如果不需要动画,直接设置
- if (duration <= 0) {
- this._currentProgress = targetProgress;
- this._updateProgressDisplay(this._currentProgress);
- return;
- }
- //使用Tween实现平滑过渡
- return new Promise<void>((resolve) => {
- if (this._progressTween) {
- this._progressTween.stop();
- }
- const startProgress = this._currentProgress;
- this._progressTween = tween({ progress: startProgress })
- .to(duration, { progress: targetProgress }, {
- onUpdate: (target) => {
- this._currentProgress = Math.floor(target.progress);
- this._updateProgressDisplay(this._currentProgress);
- },
- onComplete: () => {
- this._currentProgress = targetProgress;
- this._updateProgressDisplay(this._currentProgress);
- this._progressTween = null;
- resolve();
- }
- })
- .start();
- });
- }
- private _updateProgressDisplay(progress: number) {
- this.progressLabel.string = `${progress}%`;
- }
- }
|