1
This commit is contained in:
@@ -11,11 +11,11 @@ export type MiniGameDraftGenerationKind = 'puzzle' | 'big-fish';
|
||||
export type MiniGameDraftGenerationPhase =
|
||||
| 'idle'
|
||||
| 'compile'
|
||||
| 'big-fish-draft'
|
||||
| 'big-fish-levels'
|
||||
| 'big-fish-runtime'
|
||||
| 'puzzle-images'
|
||||
| 'puzzle-select-image'
|
||||
| 'big-fish-main-images'
|
||||
| 'big-fish-motions'
|
||||
| 'big-fish-background'
|
||||
| 'ready'
|
||||
| 'failed';
|
||||
|
||||
@@ -64,29 +64,23 @@ const PUZZLE_STEPS = [
|
||||
|
||||
const BIG_FISH_STEPS = [
|
||||
{
|
||||
id: 'compile',
|
||||
label: '编译玩法草稿',
|
||||
detail: '生成关卡角色描述、生态背景与运行参数。',
|
||||
id: 'big-fish-draft',
|
||||
label: '整理玩法骨架',
|
||||
detail: '收拢玩法承诺、成长阶梯与风险节奏。',
|
||||
weight: 30,
|
||||
},
|
||||
{
|
||||
id: 'big-fish-levels',
|
||||
label: '编译等级蓝图',
|
||||
detail: '生成每级角色描述、形象描述与动作描述。',
|
||||
weight: 45,
|
||||
},
|
||||
{
|
||||
id: 'big-fish-runtime',
|
||||
label: '校准场地与参数',
|
||||
detail: '整理背景蓝图与运行参数,准备结果页。',
|
||||
weight: 25,
|
||||
},
|
||||
{
|
||||
id: 'big-fish-main-images',
|
||||
label: '生成角色图片',
|
||||
detail: '为每个成长阶段生成主形象。',
|
||||
weight: 30,
|
||||
},
|
||||
{
|
||||
id: 'big-fish-motions',
|
||||
label: '生成动作素材',
|
||||
detail: '补齐漂浮与游动动作素材。',
|
||||
weight: 30,
|
||||
},
|
||||
{
|
||||
id: 'big-fish-background',
|
||||
label: '生成场地背景',
|
||||
detail: '生成玩法场地背景图。',
|
||||
weight: 15,
|
||||
},
|
||||
] as const satisfies ReadonlyArray<MiniGameStepDefinition>;
|
||||
|
||||
function clampProgress(value: number) {
|
||||
@@ -138,7 +132,7 @@ export function createMiniGameDraftGenerationState(
|
||||
): MiniGameDraftGenerationState {
|
||||
return {
|
||||
kind,
|
||||
phase: 'compile',
|
||||
phase: kind === 'big-fish' ? 'big-fish-draft' : 'compile',
|
||||
startedAtMs: Date.now(),
|
||||
completedAssetCount: 0,
|
||||
totalAssetCount: 0,
|
||||
@@ -146,6 +140,16 @@ export function createMiniGameDraftGenerationState(
|
||||
};
|
||||
}
|
||||
|
||||
function resolveBigFishPhaseByElapsedMs(elapsedMs: number): MiniGameDraftGenerationPhase {
|
||||
if (elapsedMs >= 4_500) {
|
||||
return 'big-fish-runtime';
|
||||
}
|
||||
if (elapsedMs >= 1_800) {
|
||||
return 'big-fish-levels';
|
||||
}
|
||||
return 'big-fish-draft';
|
||||
}
|
||||
|
||||
export function buildMiniGameDraftGenerationProgress(
|
||||
state: MiniGameDraftGenerationState | null,
|
||||
nowMs = Date.now(),
|
||||
@@ -154,46 +158,66 @@ export function buildMiniGameDraftGenerationProgress(
|
||||
return null;
|
||||
}
|
||||
|
||||
const steps = getStepDefinitions(state.kind);
|
||||
const activeStepIndex = getActiveStepIndex(steps, state.phase);
|
||||
const elapsedMs = Math.max(0, nowMs - state.startedAtMs);
|
||||
const normalizedState =
|
||||
state.kind === 'big-fish' &&
|
||||
state.phase !== 'failed' &&
|
||||
state.phase !== 'ready'
|
||||
? {
|
||||
...state,
|
||||
phase: resolveBigFishPhaseByElapsedMs(elapsedMs),
|
||||
}
|
||||
: state;
|
||||
|
||||
const steps = getStepDefinitions(normalizedState.kind);
|
||||
const activeStepIndex = getActiveStepIndex(steps, normalizedState.phase);
|
||||
const completedWeight = steps
|
||||
.slice(0, state.phase === 'ready' ? steps.length : activeStepIndex)
|
||||
.slice(0, normalizedState.phase === 'ready' ? steps.length : activeStepIndex)
|
||||
.reduce((sum, step) => sum + step.weight, 0);
|
||||
const activeStep = steps[activeStepIndex] ?? steps[0];
|
||||
const assetRatio =
|
||||
state.totalAssetCount > 0
|
||||
? Math.min(1, state.completedAssetCount / state.totalAssetCount)
|
||||
: state.phase === 'ready'
|
||||
normalizedState.totalAssetCount > 0
|
||||
? Math.min(1, normalizedState.completedAssetCount / normalizedState.totalAssetCount)
|
||||
: normalizedState.phase === 'ready'
|
||||
? 1
|
||||
: 0;
|
||||
: normalizedState.kind === 'big-fish'
|
||||
? 0.55
|
||||
: 0;
|
||||
const overallProgress =
|
||||
state.phase === 'failed'
|
||||
normalizedState.phase === 'failed'
|
||||
? Math.max(1, completedWeight)
|
||||
: state.phase === 'ready'
|
||||
: normalizedState.phase === 'ready'
|
||||
? 100
|
||||
: completedWeight + activeStep.weight * assetRatio;
|
||||
|
||||
return {
|
||||
phaseId: state.phase,
|
||||
phaseId: normalizedState.phase,
|
||||
phaseLabel:
|
||||
state.phase === 'failed'
|
||||
normalizedState.phase === 'failed'
|
||||
? '生成失败'
|
||||
: state.phase === 'ready'
|
||||
: normalizedState.phase === 'ready'
|
||||
? '生成完成'
|
||||
: activeStep.label,
|
||||
phaseDetail:
|
||||
state.error ??
|
||||
(state.phase === 'ready'
|
||||
? '完整草稿与资产已准备完成。'
|
||||
normalizedState.error ??
|
||||
(normalizedState.phase === 'ready'
|
||||
? normalizedState.kind === 'big-fish'
|
||||
? '玩法草稿已准备完成,可进入结果页继续生成主图、动作和背景。'
|
||||
: '完整草稿与资产已准备完成。'
|
||||
: activeStep.detail),
|
||||
batchLabel: activeStep.label,
|
||||
overallProgress: clampProgress(overallProgress),
|
||||
completedWeight: clampProgress(overallProgress),
|
||||
totalWeight: 100,
|
||||
elapsedMs: Math.max(0, nowMs - state.startedAtMs),
|
||||
estimatedRemainingMs: state.phase === 'ready' ? 0 : null,
|
||||
elapsedMs,
|
||||
estimatedRemainingMs:
|
||||
normalizedState.phase === 'ready'
|
||||
? 0
|
||||
: normalizedState.kind === 'big-fish'
|
||||
? Math.max(0, 7_000 - elapsedMs)
|
||||
: null,
|
||||
activeStepIndex,
|
||||
steps: buildMiniGameProgressSteps(steps, activeStepIndex, state),
|
||||
steps: buildMiniGameProgressSteps(steps, activeStepIndex, normalizedState),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user