消消方块阵换皮表情
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
5.8 KiB

1 week ago
import { BattleResLoader } from './BattleResLoader';
import { GBundle, getBattleMapResItemByChapter, ResPkgName } from './ConfigRes';
/**
* Home
* -
5 days ago
* - bundletetriGame/Map/Cards/Weapon + battleGameWeapon +
1 week ago
* - weapon1 + hitEffect
*
*
* /// pause Home 2s resume
* yield loadBundle
*/
export class HomeBattlePreload {
private static readonly RESUME_DELAY_MS = 2000;
/** 战斗结束回大厅后错峰预载(与 releaseBundle 错开,减轻卡顿) */
private static readonly POST_BATTLE_RESUME_MS = 1500;
/** Home 相关局内分包(只拉 bundle 索引,具体 prefab 再 ensure) */
private static readonly BATTLE_BUNDLES: string[] = [
GBundle.tetriGame,
GBundle.tetriMap,
GBundle.tetriCards,
GBundle.tetriWeapon,
GBundle.BattleGameWeapon,
5 days ago
GBundle.BattleGameResult,
GBundle.SkillSelect,
GBundle.TurnTable,
GBundle.tetriDoc,
1 week ago
];
private static _paused = false;
private static _gen = 0;
private static _chapterId = 0;
private static _resumeTimer: ReturnType<typeof setTimeout> | null = null;
private static _running = false;
/** Home 创建完成 / 切章节:立即开始(取消延迟) */
static startNow(chapterId: number): void {
if (!chapterId || chapterId <= 0) return;
this._clearResumeTimer();
this._paused = false;
this._chapterId = chapterId;
void this._run(chapterId);
}
/** 切走 Home:暂停,丢弃进行中的预载代际 */
static pause(): void {
this._clearResumeTimer();
this._paused = true;
this._gen++;
}
/**
* releaseBundle 线
*/
static resumeAfterBattle(chapterId?: number): void {
const id = chapterId > 0
? chapterId
: (this._chapterId || gg?.game?.CurentSelectChapterId || gg?.data?.doc?.chapter || 0);
if (!id) return;
this.scheduleResume(id, HomeBattlePreload.POST_BATTLE_RESUME_MS);
}
/** 切回 Home:等待 delayMs 后再开(默认 2s) */
static scheduleResume(chapterId?: number, delayMs: number = HomeBattlePreload.RESUME_DELAY_MS): void {
const id = chapterId > 0 ? chapterId : (this._chapterId || gg?.game?.CurentSelectChapterId || 0);
this.pause();
if (!id) return;
this._chapterId = id;
this._resumeTimer = setTimeout(() => {
this._resumeTimer = null;
if (gg?.game?.CurentBattle) return;
this._paused = false;
void this._run(this._chapterId);
}, delayMs);
}
private static _clearResumeTimer(): void {
if (this._resumeTimer != null) {
clearTimeout(this._resumeTimer);
this._resumeTimer = null;
}
}
private static _alive(gen: number): boolean {
return !this._paused && this._gen === gen && !gg?.game?.CurentBattle;
}
/** 让出主线程一帧,避免连续 loadBundle 造成卡顿尖刺 */
private static _yieldFrame(): Promise<void> {
return new Promise((resolve) => {
setTimeout(resolve, 0);
});
}
private static _logDone(task: string): void {
console.log(`[HomeBattlePreload] 加载完成: ${task}`);
}
private static async _run(chapterId: number): Promise<void> {
const gen = ++this._gen;
this._chapterId = chapterId;
this._running = true;
console.log(`[HomeBattlePreload] 开始预载 chapter=${chapterId}`);
try {
if (!this._alive(gen)) return;
await BattleResLoader.ensureBattleEntry();
if (!this._alive(gen)) return;
this._logDone('ensureBattleEntry(home/audio)');
await this._yieldFrame();
for (let i = 0; i < this.BATTLE_BUNDLES.length; i++) {
const bundleName = this.BATTLE_BUNDLES[i];
await BattleResLoader.loadBundle(bundleName);
if (!this._alive(gen)) return;
this._logDone(`bundle/${bundleName}`);
await this._yieldFrame();
}
const mapItem = getBattleMapResItemByChapter(chapterId);
if (mapItem && gg?.res) {
await gg.res.ensurePrefab(mapItem.name, mapItem.path, mapItem.bundle);
if (!this._alive(gen)) return;
gg.res.appendToResPkg(ResPkgName.BattleRes, [mapItem]);
this._logDone(`地图 ${mapItem.bundle}/${mapItem.path}${mapItem.name}`);
await this._yieldFrame();
} else {
console.warn(`[HomeBattlePreload] 章节${chapterId} 无地图配置,跳过地图预载`);
}
if (gg?.res) {
await gg.res.ensurePrefab('tetriGame', 'prefab/', GBundle.tetriGame);
if (!this._alive(gen)) return;
this._logDone(`界面 ${GBundle.tetriGame}/prefab/tetriGame`);
await this._yieldFrame();
}
await BattleResLoader.preloadWeapon1Bullet();
if (!this._alive(gen)) return;
const hit = gg?.data?.project?.getWeaponData?.(1)?.hitEffect ?? '';
this._logDone(`weapon1 子弹 + hitEffect(${hit || '无'})`);
this._logDone(`章节${chapterId} 全部预载任务结束`);
} catch (e) {
console.warn('[HomeBattlePreload] run failed', chapterId, e);
} finally {
if (this._gen === gen) {
this._running = false;
}
}
}
}