Optimize initial loading performance
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import Phaser from 'phaser';
|
||||
import storyMilitiaUrl from '../../assets/images/story/04-volunteer-militia.png';
|
||||
import { soundDirector } from '../audio/SoundDirector';
|
||||
import { equipmentExpToNext, equipmentSlotLabels, equipmentSlots, getItem, type EquipmentSlot } from '../data/battleItems';
|
||||
import { getUnitClass, terrainRules, type TerrainType } from '../data/battleRules';
|
||||
import { defaultBattleScenario, getBattleScenario, type BattleScenarioDefinition, type BattleScenarioId } from '../data/battles';
|
||||
import { getSortieFlow } from '../data/campaignFlow';
|
||||
import { portraitAssetEntriesForKey, portraitTextureKey, type PortraitAssetEntry } from '../data/portraitAssets';
|
||||
import {
|
||||
caoBreakRecruitBonds,
|
||||
caoBreakRecruitUnits,
|
||||
@@ -94,6 +96,7 @@ import {
|
||||
type FirstBattleReport
|
||||
} from '../state/campaignState';
|
||||
import { palette } from '../ui/palette';
|
||||
import { startLazyScene } from './lazyScenes';
|
||||
|
||||
type CampTab = 'status' | 'dialogue' | 'visit' | 'supplies' | 'progress';
|
||||
|
||||
@@ -254,16 +257,6 @@ type CampaignTimelineChapter = {
|
||||
nextHints: string[];
|
||||
};
|
||||
|
||||
const portraitKeys: Record<PortraitKey, string> = {
|
||||
liuBei: 'portrait-liu-bei',
|
||||
guanYu: 'portrait-guan-yu',
|
||||
zhangFei: 'portrait-zhang-fei',
|
||||
zhugeLiang: 'portrait-zhuge-liang',
|
||||
zhaoYun: 'portrait-zhao-yun',
|
||||
jiangWei: 'portrait-jiang-wei',
|
||||
simaYi: 'portrait-sima-yi'
|
||||
};
|
||||
|
||||
const portraitByUnitId: Record<string, PortraitKey> = {
|
||||
'liu-bei': 'liuBei',
|
||||
'guan-yu': 'guanYu',
|
||||
@@ -10028,7 +10021,10 @@ export class CampScene extends Phaser.Scene {
|
||||
this.selectedDialogueId = this.availableCampDialogues()[0]?.id ?? campDialogues[0].id;
|
||||
this.selectedVisitId = this.availableCampVisits()[0]?.id ?? campVisits[0].id;
|
||||
soundDirector.playMusic('militia-theme');
|
||||
this.ensureCampAssets(() => this.drawCampScene());
|
||||
}
|
||||
|
||||
private drawCampScene() {
|
||||
const { width, height } = this.scale;
|
||||
this.add.image(width / 2, height / 2, 'story-militia').setDisplaySize(width * 1.08, height * 1.08).setAlpha(0.62);
|
||||
this.add.rectangle(0, 0, width, height, 0x06090d, 0.54).setOrigin(0);
|
||||
@@ -10052,6 +10048,46 @@ export class CampScene extends Phaser.Scene {
|
||||
this.render();
|
||||
}
|
||||
|
||||
private ensureCampAssets(onReady: () => void) {
|
||||
const missingPortraits = this.currentUnits()
|
||||
.map((unit) => {
|
||||
const portraitKey = portraitByUnitId[unit.id];
|
||||
return portraitKey ? portraitAssetEntriesForKey(portraitKey)[0] : undefined;
|
||||
})
|
||||
.filter((entry): entry is PortraitAssetEntry => entry !== undefined)
|
||||
.filter((entry, index, entries) => entries.findIndex((candidate) => candidate.textureKey === entry.textureKey) === index)
|
||||
.filter((entry) => !this.textures.exists(entry.textureKey));
|
||||
const missingMilitia = !this.textures.exists('story-militia');
|
||||
|
||||
if (!missingMilitia && missingPortraits.length === 0) {
|
||||
onReady();
|
||||
return;
|
||||
}
|
||||
|
||||
const loadingText = this.add.text(this.scale.width / 2, this.scale.height / 2, 'Camp loading...', {
|
||||
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
|
||||
fontSize: '22px',
|
||||
color: '#f5e6b8',
|
||||
stroke: '#05070a',
|
||||
strokeThickness: 4
|
||||
});
|
||||
loadingText.setOrigin(0.5);
|
||||
|
||||
this.load.once('complete', () => {
|
||||
loadingText.destroy();
|
||||
onReady();
|
||||
});
|
||||
this.load.once('loaderror', (file: Phaser.Loader.File) => {
|
||||
console.warn(`Failed to load camp asset ${file.key}`);
|
||||
});
|
||||
|
||||
if (missingMilitia) {
|
||||
this.load.image('story-militia', storyMilitiaUrl);
|
||||
}
|
||||
missingPortraits.forEach(({ textureKey, url }) => this.load.image(textureKey, url));
|
||||
this.load.start();
|
||||
}
|
||||
|
||||
private createFallbackReport(): FirstBattleReport {
|
||||
const allies = firstBattleUnits.filter((unit) => unit.faction === 'ally');
|
||||
return {
|
||||
@@ -12015,14 +12051,14 @@ export class CampScene extends Phaser.Scene {
|
||||
}
|
||||
markCampaignStep(flow.campaignStep);
|
||||
this.campaign = getCampaignState();
|
||||
this.scene.start('StoryScene', {
|
||||
void startLazyScene(this, 'StoryScene', {
|
||||
pages: flow.pages,
|
||||
nextScene: flow.campaignStep === 'ending-complete' ? 'EndingScene' : 'CampScene'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (flow.pages.length > 0) {
|
||||
this.scene.start('StoryScene', {
|
||||
void startLazyScene(this, 'StoryScene', {
|
||||
pages: flow.pages,
|
||||
nextScene: 'CampScene'
|
||||
});
|
||||
@@ -12041,7 +12077,7 @@ export class CampScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
markCampaignStep(flow.campaignStep);
|
||||
this.scene.start('StoryScene', {
|
||||
void startLazyScene(this, 'StoryScene', {
|
||||
pages: flow.pages,
|
||||
nextScene: 'BattleScene',
|
||||
nextSceneData: { battleId: flow.nextBattleId }
|
||||
@@ -12095,10 +12131,11 @@ export class CampScene extends Phaser.Scene {
|
||||
});
|
||||
|
||||
const portraitKey = portraitByUnitId[unit.id];
|
||||
const portraitTexture = portraitKey ? portraitTextureKey(portraitKey) : undefined;
|
||||
const portraitCenterY = y + cardHeight / 2;
|
||||
const portraitSize = compact ? 40 : 84;
|
||||
if (portraitKey) {
|
||||
const portrait = this.track(this.add.image(x + 58, portraitCenterY, portraitKeys[portraitKey]));
|
||||
if (portraitTexture && this.textures.exists(portraitTexture)) {
|
||||
const portrait = this.track(this.add.image(x + 58, portraitCenterY, portraitTexture));
|
||||
portrait.setDisplaySize(portraitSize, portraitSize);
|
||||
} else {
|
||||
this.renderUnitFallbackPortrait(x + 58, portraitCenterY, compact ? 20 : 40, unit);
|
||||
@@ -12427,10 +12464,11 @@ export class CampScene extends Phaser.Scene {
|
||||
|
||||
const unitClass = getUnitClass(unit.classKey);
|
||||
const portraitKey = portraitByUnitId[unit.id];
|
||||
const portraitTexture = portraitKey ? portraitTextureKey(portraitKey) : undefined;
|
||||
const portraitFrame = this.track(this.add.rectangle(x + 84, y + 90, 122, 122, 0x0b1219, 0.92));
|
||||
portraitFrame.setStrokeStyle(2, palette.gold, 0.62);
|
||||
if (portraitKey) {
|
||||
const portrait = this.track(this.add.image(x + 84, y + 90, portraitKeys[portraitKey]));
|
||||
if (portraitTexture && this.textures.exists(portraitTexture)) {
|
||||
const portrait = this.track(this.add.image(x + 84, y + 90, portraitTexture));
|
||||
portrait.setDisplaySize(112, 112);
|
||||
} else {
|
||||
this.renderUnitFallbackPortrait(x + 84, y + 90, 48, unit);
|
||||
|
||||
Reference in New Issue
Block a user