This commit is contained in:
2026-04-28 19:36:39 +08:00
parent a9febe7678
commit f0471a4f8d
206 changed files with 18456 additions and 10133 deletions

View File

@@ -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),
};
}