import { _decorator, assetManager, Camera, Component, director, Game, game, Label, Node, } from 'cc'; import { GBundle, UIID, UIConfigs, GPath, getCommResPakage } from './game/ConfigRes'; import { clamp01 } from 'cc'; import { Sprite } from 'cc'; import { GameController } from './game/GameController'; import { GM } from './game/GM'; import { DEBUG, IOS } from 'cc/env'; import { sdkConfig } from './sdk/sdkConfig'; import { PhysicsSystem2D } from 'cc'; import { GEvent } from '../mx/module/event/GEvent'; import { applyCacheManagerPatch } from "./minigame/CacheManagerPatch"; import { BattleDataManager } from './ui/BattleGame/BattleDataManager'; import { BattlePerformance } from './ui/BattleGame/BattlePerformance'; const { ccclass, property } = _decorator; @ccclass('GameLaunch') export class GameLaunch extends Component { static instantiate: GameLaunch = null; @property(Node) Loading: Node; @property(Label) title: Label; @property(Node) netUI: Node; @property(Node) loadingUI: Node; @property(Node) mapParent: Node; private _progress = 0; /** 公共资源包加载完成 */ private _firstResReady = false; /** 配表 loadConfig 完成且 gg.data.init 执行完毕 */ private _sdkAndDataReady = false; /** 游戏bundle加载完成 */ private _gameBundleReady = false; protected onLoad(): void { applyCacheManagerPatch(); GameLaunch.instantiate = this; if (assetManager.cacheManager) { assetManager.cacheManager.autoClear = true; // assetManager.cacheManager.clearLRU(); } const ph2d = PhysicsSystem2D.instance; ph2d.enable = true; // 固定步长;每帧 maxSubSteps 由 UItetraGame.update(dt) 按 dt 动态计算(非方块战斗场景仍用引擎默认 maxSubSteps)。 ph2d.fixedTimeStep = 1 / 60; GEvent.Ins.on(GEvent.SHOW_NET_UI, this.showNetUI, this); GEvent.Ins.on(GEvent.HIDE_NET_UI, this.closeNetUI, this); GEvent.Ins.on(GEvent.SHOW_LOADING, this.showLoading, this); GEvent.Ins.on(GEvent.HIDE_LOADING, this.hideLoading, this); // game.on(Game.EVENT_SHOW, this.onShow, this) // game.on(Game.EVENT_HIDE, this.onHide, this) } // onShow() { // console.log("onShow") // game.resume(); // } // onHide() { // console.log("onHide") // game.pause(); // } protected update(dt: number): void { this.Loading.getChildByName("progress").getComponent(Sprite).fillRange = clamp01(this._progress); gg.sdk.serverTime += dt * 1000; } async start() { if (DEBUG) { window["gg"] = gg; window["gm"] = GM; window["setBattlePerfProfile"] = (profile: 'auto' | 'ios' | 'android' | 'douyin') => { BattlePerformance.setBrowserPerfProfile(profile); }; console.log( `[BattlePerf] 浏览器预览 active=${BattlePerformance.activePerfProfile()} ` + `(config=${sdkConfig.browserBattlePerfProfile},改档: setBattlePerfProfile('ios'|'android'))`, ); //GM.show(); } await gg.lang.init(sdkConfig.defaultLang); const scene = director.getScene(); let uiCamera = scene.find("Camera")?.getComponent(Camera); let gameCamera = scene.find("gamCamare")?.getComponent(Camera) gg.ui.init(UIConfigs, uiCamera, gameCamera, false); gg.audio.init({ bundle: GBundle.Audio, clickEffname: "点击音效" }); gg.game = this.addComponent(GameController); this.loadFirstRes(); this.loadTableData(); this.loadGameBundle() } /** 分包模式下须先 loadBundle 完成再访问资源;comm2/home 等依赖 comm、first、main */ private loadBundleAsync(bundleName: string): Promise { if (assetManager.getBundle(bundleName)) { return Promise.resolve(true); } return new Promise((resolve) => { assetManager.loadBundle(bundleName, (err) => { if (err) { console.error(`[GameLaunch] loadBundle ${bundleName} 失败`, err); gg.sdk?.pfLogKey?.('RES:BUNDLE_FAIL', `launch:${bundleName}`); resolve(false); } else { resolve(true); } }); }); } /** 按依赖顺序分批加载,同批内并行 */ private async loadBundlesOrdered(groups: string[][]): Promise { for (const group of groups) { await Promise.all(group.map((name) => this.loadBundleAsync(name))); } } loadGameBundle() { // 战斗相关分包改到进战斗时再加载,启动阶段不再预拉 this._gameBundleReady = true; this.tryEnterGame(); } async loadFirstRes() { this.title.string = "正在更新资源..."; // 分包有依赖:comm2→comm/first/main,home→comm2… 必须等 loadBundle 完成再 load 资源 await this.loadBundlesOrdered([ ['main', GBundle.Comm], [GBundle.First], ]); this._progress += 0.1; // onProgress 的 c/t 是“累计比例”,不能直接用 += c/t * weight(会重复累计导致很快到 1) let lastRatio = 0; gg.res.loadResPakg(getCommResPakage(), (c, t) => { const ratio = t > 0 ? (c / t) : 0; const delta = ratio - lastRatio; lastRatio = ratio; this._progress += delta * 0.2; }, () => { //this.title.string = "资源加载完成"; console.log("资源加载完成"); this._firstResReady = true; this.tryEnterGame(); }); } loadTableData() { // onProgress 的 c/t 是“累计比例”,不能直接用 += c/t * weight(会重复累计导致很快到 1) let lastRatio = 0; gg.data.table.loadConfig((c, t) => { const ratio = t > 0 ? (c / t) : 0; const delta = ratio - lastRatio; lastRatio = ratio; this._progress += delta * 0.25; }, () => { console.log("配表加载完成"); this.initSdk(); }) } async initSdk() { let startTime2 = new Date().getTime() let data = await gg.sdk.init(); let uid = await ZYSDK.ZYSDK.getUserId(); gg.data.doc.uid = uid; sdkConfig.sdkLoadFinishTime = new Date().getTime() - startTime2 gg.data.init(sdkConfig.config.pointData.gid, data); console.log("sdk初始化完成"); this._progress += 0.25; this._sdkAndDataReady = true; this.tryEnterGame(); } /** * 仅在「首包资源就绪」且「配表 + SDK + gg.data.init」都完成后再进游戏, * 避免 enterMain / initCurTargetTaskConfig 早于配表与存档就绪。 */ private async tryEnterGame() { if (!this._firstResReady || !this._sdkAndDataReady || !this.Loading.active || !this._gameBundleReady) { return; } if (this._progress < 1) { this._progress = 1; } await BattleDataManager.getLeveData(); gg.game.init(); this.Loading.active = false; } showNetUI() { if (this.netUI) this.netUI.active = true; } closeNetUI() { if (this.netUI) this.netUI.active = false; } showLoading(index: number = 2) { if (this.loadingUI) { this.loadingUI.active = true; this.loadingUI.find("1").active = index == 1; this.loadingUI.find("2").active = index == 2; } } hideLoading() { if (this.loadingUI) this.loadingUI.active = false; } }