namespace LivingVillage.Desktop /// 启动画面:固定的 60Hz 步进下,全部为帧计数的纯函数,确定性可复现。 /// 标题淡入(revealProgress)、整屏暗幕退场(veilAlpha),Esc/空格可随时跳过。 module LaunchScreen = let durationFrames = 150L let fadeInFrames = 45L let title = "江南水乡" let subtitle = "Living Village" let skipHint = "ESC 或 空格 跳过" let private clamp01 (value: float32) : float32 = if value < 0.0f then 0.0f elif value > 1.0f then 1.0f else value /// 0 = 完全未显示,1 = 完全显现。帧计数纯函数。 let revealProgress (frame: int64) : float32 = if frame <= 0L then 0.0f else clamp01 (float32 frame / float32 fadeInFrames) /// 整屏暗幕:起手 1,随进程退到 0(1 -> 0)。 let veilAlpha (frame: int64) : float32 = if frame <= 0L then 1.0f elif frame >= durationFrames then 0.0f else 1.0f - clamp01 (float32 frame / float32 durationFrames) let isComplete (frame: int64) : bool = frame >= durationFrames /// Esc 或 空格 触发跳过(调用方用“按下沿”结果,不做按键状态判定)。 let skipRequested (escapePressed: bool) (spacePressed: bool) : bool = escapePressed || spacePressed /// P16-FIX 证据补拍:开始界面菜单截图的确定性帧表(纯数据,Game 与回归测试共用)。 /// 帧号均为 60Hz Update 计数:splash 淡入中 -> 菜单入场完成(初始高亮「开始」)-> 向下 /// -> 高亮「读档」-> 退出。输出文件名不含目录与扩展名。 module MenuShotScript = let splashMidName = "frame-splash-mid-01" let initialName = "menu-real-initial" let loadName = "menu-real-load" let splashMidFrame = 30L let initialFrame = 130L let downFrame = 140L let loadFrame = 150L let exitFrame = 170L /// P42 取证:环境动效证据帧表(60Hz 帧号纯数据,Game 与回归测试共用)。 /// splash 两帧都落在水面尚可见的阶段(reveal<1),菜单帧取入场完成后的动画相位。 module P42ShotScript = let splashEarlyName = "p42-splash-1" let splashLateName = "p42-splash-2" let menuName = "p42-menu-anim" let splashEarlyFrame = 10L let splashLateFrame = 28L let menuFrame = 150L