import { _decorator, Component, Node, ProgressBar, Label, UITransform, tween, JsonAsset, Button, } from "cc"; import { callGameApi, callGameApiForRank, callGamePendingApi, getGameId, getIsRB7, getLanguage, getTestToken, initReqAddr, } from "./comm"; import { I18nManager } from "../managers/I18nManager"; import { AudioManager } from "../managers/AudioManager"; import { GameDataManager } from "../managers/GameDataManager"; import { ResManager } from "../managers/ResManager"; import { NodePoolManager } from "../managers/NodePoolManager"; import { DEBUG } from "cc/env"; import { LocalizedSprite } from "../i18n/LocalizedSprite"; import { initErrorManager } from "../managers/ErrorManager"; import { LocalizedLabel } from "../i18n/LocalizedLabel"; const { ccclass, property } = _decorator; @ccclass("Loading") export class Loading extends Component { // UI组件 @property(Node) progressNode: Node = null; @property(ProgressBar) progressBar: ProgressBar = null; @property(Label) progressLabel: Label = null; @property(Label) loadingLabel: Label = null; @property(Node) maskSpineNode: Node = null; @property(Node) lightSpineNode: Node = null; @property(Node) startBtnNode: Node = null; @property(Node) rb7Logo: Node = null; @property(JsonAsset) languageJson: JsonAsset = null; @property(Label) tipLabel: Label = null; @property(Button) startBtn: Button = null; @property(Label) startBtnLabel: Label = null; private _networkComplete = false; private _retryCount = 0; private readonly MAX_RETRY = 5; // 加载状态 private isNetworkReady = false; private readonly PROGRESS_ANIMATION_DURATION = 0.3; // 进度条阶段 private readonly PROGRESS_INIT = 0.2; // 初始化完成 private readonly PROGRESS_NETWORK = 0.5; // 网络请求完成 private readonly PROGRESS_RESOURCE = 0.9; // 资源加载完成 private readonly PROGRESS_COMPLETE = 1.0; // 完全加载完成 // 游戏节点 private gameContainer: Node = null; private gameNode: Node = null; protected async onLoad() { initReqAddr(); let language = getLanguage(); this.node.getChildByName('logo_zh').active = language === 'zh'; this.node.getChildByName('logo_en').active = language !== 'zh'; initErrorManager(); await I18nManager.instance.ensureI18nSprite(language, "logo1"); this.node .getChildByName("logo1") .getComponent(LocalizedSprite) .updateSpriteForPreload(language); this.node.getChildByName("logo1").active = true; await I18nManager.instance.init(language, this.languageJson); I18nManager.instance.updateSceneRenderers(); this.initializeUI(); // 初始化完成,进度条到20% this.updateProgress(this.PROGRESS_INIT); try { await this.initializeSystem(); AudioManager.instance.init(); this.updateLoadingText("Loading"); // 延迟一下让用户看到进度条开始 this.scheduleOnce(() => { this.startNetworkLoading(); }, 0.2); } catch (error) { console.error("Network initialization failed:", error); this.handleError(error); } } /** 初始化系统 */ private async initializeSystem() { this.rb7Logo.active = getIsRB7(); if (DEBUG) { await getTestToken("xingxi", "faketrans"); } } /** 初始化UI */ private initializeUI() { this.startBtnNode.active = false; this.gameContainer = this.node.parent .getChildByName("main") .getChildByName("game"); // 初始化进度条为0 this.updateProgress(0); } /** 开始网络加载 */ private async startNetworkLoading() { this.updateLoadingText("Loading"); try { let gamePending = await callGamePendingApi({ GameId: getGameId() }); if (gamePending.Data.length > 0) { GameDataManager.instance.gamePending = gamePending.Data[0]; GameDataManager.instance.chooseDiff = +gamePending.Data[0].split('_')[2]; } else { if (localStorage.getItem('HasGamePending') !== null) { GameDataManager.instance.gamePending = String(getGameId()) + '_' + localStorage.getItem('HasGamePending'); GameDataManager.instance.chooseDiff = +localStorage.getItem('HasGamePending'); } else { GameDataManager.instance.chooseDiff = 2; GameDataManager.instance.gamePending = getGameId() + '_' + 2; } } let gameInfo = await callGameApi("gameinfo", {}); GameDataManager.instance.gameInfo = gameInfo; this.isNetworkReady = true; // 网络请求完成,进度条到50% this.updateProgress(this.PROGRESS_NETWORK); // 稍微延迟一下让用户看到进度变化 this.scheduleOnce(() => { this.startResourceLoading(); }, 0.3); } catch (error) { console.error("Network initialization failed:", error); this.handleError(error); } } /** 开始资源加载 */ private async startResourceLoading() { if (!this.isNetworkReady) return; this.tipLabel.string = I18nManager.instance.t("AID_LOADING"); this.startBtnNode.active = false; this.gameNode = await ResManager.instance.loadPrefabFromBundle( "Game", "SlotScene", (finished: number, total: number) => { if (total > 0) { // 资源加载进度从50%到90% const resourceProgress = finished / total; const currentProgress = this.PROGRESS_NETWORK + resourceProgress * (this.PROGRESS_RESOURCE - this.PROGRESS_NETWORK); this.updateProgress(currentProgress); } } ); // 资源加载完成,进度条到90% this.updateProgress(this.PROGRESS_RESOURCE); // 延迟一下然后完成最后的10% this.scheduleOnce(() => { this.finishLoading(); }, 0.2); } /** 完成加载 */ private finishLoading() { this.updateLoadingText("Loading More..."); // 最后10%快速完成 this.updateProgress(this.PROGRESS_COMPLETE); // 0.5秒后显示开始按钮 this.scheduleOnce(() => { this.onLoadComplete(); }, 0.5); } /** 更新进度条 */ private updateProgress(progress: number) { tween(this.progressBar) .to( this.PROGRESS_ANIMATION_DURATION, { progress }, { easing: "smooth", onUpdate: (target: any) => { const currentProgress = target.progress; this.progressLabel.string = `${Math.floor(currentProgress * 100)}%`; this.maskSpineNode .getComponent(UITransform) .setContentSize(currentProgress * 509, 100); this.lightSpineNode.setPosition( currentProgress * 509 - 268, -522, 0 ); }, } ) .start(); } /** 更新加载文本 */ private updateLoadingText(key: string) { this.loadingLabel.string = I18nManager.instance.t("AID_LOADING"); } /** 加载完成 */ private onLoadComplete() { this.startBtnLabel.string = I18nManager.instance.t("AID_GET_STARTED"); this.hideProgressUI(); this.showStartButton(); } /** 隐藏进度UI */ private hideProgressUI() { this.loadingLabel.string = ""; this.progressBar.node.active = false; this.progressLabel.node.active = false; this.maskSpineNode.active = false; this.lightSpineNode.active = false; } /** 显示开始按钮 */ private showStartButton() { this.startBtnNode.children[0].getComponent(LocalizedLabel).updateLabel(); this.startBtnNode.active = true; } /** 开始游戏 */ private startGame() { if (!this.gameContainer) { console.error("Game container not found"); return; } this.gameContainer.addChild(this.gameNode); this.node.destroy(); } /** 按钮点击事件 */ onStartBtnClick() { if ( this.startBtnLabel.string === I18nManager.instance.t("AID_ERROR_RETRY_BUTTON") ) { // 重试逻辑 this._retryCount = 0; this.startBtn.node.active = false; this.progressBar.node.active = true; this.progressLabel.node.active = true; if (!this._networkComplete) { this.startNetworkLoading(); } else { this.startResourceLoading(); } } else { this.startGame(); } } private handleError(error: Error) { this._retryCount++; if (this._retryCount <= this.MAX_RETRY) { // 自动重试 // this.tipLabel.string = `retry(${this._retryCount}/${this.MAX_RETRY})...`; switch (this._retryCount) { case 1: this.tipLabel.string = I18nManager.instance.t("AID_NETWORK_RETRY_1"); break; case 2: this.tipLabel.string = I18nManager.instance.t("AID_NETWORK_RETRY_2"); break; case 3: this.tipLabel.string = I18nManager.instance.t("AID_NETWORK_RETRY_3"); break; case 4: this.tipLabel.string = I18nManager.instance.t("AID_NETWORK_RETRY_4"); break; case 5: this.tipLabel.string = I18nManager.instance.t("AID_NETWORK_RETRY_5"); break; } this.scheduleOnce(() => { if (!this._networkComplete) { this.startNetworkLoading(); } else { this.startResourceLoading(); } }, 2); } else { // 显示重试按钮 this.tipLabel.string = I18nManager.instance.t("AID_LOADING"); this.startBtn.node.active = true; this.progressBar.node.active = false; this.progressLabel.node.active = false; this.startBtnLabel.string = I18nManager.instance.t( "AID_ERROR_RETRY_BUTTON" ); } } onDestroy() { this.unscheduleAllCallbacks(); tween(this.progressBar).stop(); NodePoolManager.instance.clearAll(); } }