summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/Game.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-29 11:08:32 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-29 11:08:32 +0800
commit837fd81a2bd857011855ca1dc32e646629f14236 (patch)
tree896e33d5948bb5457cf0dd17494792f9aa631cd2 /src/LivingVillage.Desktop/Game.fs
parentf3ad37b1d057566a9e5e01a7ee9850eb1c4598f4 (diff)
downloadliving-village-837fd81a2bd857011855ca1dc32e646629f14236.tar.gz
p74: 启动开场过渡(水墨式渐显)+ 开始界面布局回归
新增纯函数 InkReveal.fs(inkStrength ease-out 消散 + 6 滴预乘墨滴 dabs),DrawSplash 在场景层之上、标题之下绘制,与既有 reveal/veil 淡入叠加,形成可辨识水墨开场;单滴 alpha<255 且椭圆行落成,无实心黑块。开始界面沿用既有 开始/读档/退出(有档 继续)。新增 P74LaunchTransitionTests(4 例)与 LV_P74_SHOT/-analyze-p74 证据(5 帧墨幕非增、两两 diff>0,verdict=PASS)。HUD 结构未动;Desktop 350/350、Kernel 120/120、digest 与 p70 一致。
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
-rw-r--r--src/LivingVillage.Desktop/Game.fs29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs
index 3d04ca7..a4f994b 100644
--- a/src/LivingVillage.Desktop/Game.fs
+++ b/src/LivingVillage.Desktop/Game.fs
@@ -319,6 +319,10 @@ type LivingVillageGame() as this =
let p42ShotMode = Environment.GetEnvironmentVariable("LV_P42_SHOT") = "1"
let mutable p42SplashEarlyDone = false
let mutable p42SplashLateDone = false
+ // P74 证据钩子:LV_P74_SHOT=1 时在 60Hz 固定步进下按 splash 帧表拍开场过渡序列,拍完退出。
+ let p74ShotMode = Environment.GetEnvironmentVariable("LV_P74_SHOT") = "1"
+ let p74Frames = [ 8L; 30L; 60L; 100L; 140L ]
+ let mutable p74Saved = Set.empty<int64>
// P43 证据钩子:LV_P43_SHOT=1 时在真实世界里拍昼/夜两张 HUD 整帧(日历钟卡 + 体力条 + 10 格 hotbar)。
let p43ShotMode = Environment.GetEnvironmentVariable("LV_P43_SHOT") = "1"
let mutable p43Step = 0
@@ -2617,6 +2621,20 @@ type LivingVillageGame() as this =
printfn "p42-shot=done"
this.Exit()
+ /// P74 证据:splash 帧表逐帧落盘(证明开场过渡在变),拍完即退出。
+ member private this.CaptureP74Shot () =
+ if splashActive then
+ match p74Frames |> List.tryFind (fun f -> not (Set.contains f p74Saved) && splashFrame >= f) with
+ | Some frame ->
+ p74Saved <- Set.add frame p74Saved
+ System.IO.Directory.CreateDirectory recordDirectory |> ignore
+ this.SaveBackBuffer(sprintf "%s/p74-splash-%03d.png" recordDirectory frame)
+ printfn "p74-shot=p74-splash-%03d inkStrength=%.3f" frame (InkReveal.inkStrength splashFrame)
+ | None -> ()
+ if p74Saved.Count >= p74Frames.Length then
+ printfn "p74-shot=done"
+ this.Exit()
+
/// P20 证据:把一次 MapGen 绘制渲染到指定尺寸离屏 target,返回绘制瓦片数与纹理。
/// P28:可传入世界 tint 与可选 veil tick(夜景取证用)。
member private this.RenderMapGen (targetWidth: int) (targetHeight: int) (camX: int) (camY: int) (drawFitted: bool) (tint: Color) (veilTick: int64 option) : int * Texture2D =
@@ -2867,6 +2885,8 @@ type LivingVillageGame() as this =
this.CaptureMenuShot()
if p42ShotMode then
this.CaptureP42Shot()
+ if p74ShotMode then
+ this.CaptureP74Shot()
if storyShotMode && storyShotPrepared then
storyShotFrame <- storyShotFrame + 1L
if not storyShotSaved && storyShotFrame = 20L then
@@ -2990,6 +3010,15 @@ type LivingVillageGame() as this =
spriteBatch.Draw(pixel, Rectangle(lx - 1, ly - 7, 4, 2), Color(90, 60, 40))
spriteBatch.Draw(pixel, Rectangle(lx - 2, ly + 5, 6, 2), Color(90, 60, 40))
+ // P74 水墨式渐显:柔和墨滴从画布各处晕开、随帧消散,露出后方天色/水面/屋脊。
+ // 单滴 alpha < 255 且用预乘椭圆行落成,绝无实心黑块;绘在标题之下、场景之上。
+ let inkR, inkG, inkB = InkReveal.inkRgb
+ for dab in InkReveal.dabs splashFrame width height do
+ if dab.Alpha > 0 then
+ let inkColor = VillageArt.premultiply inkR inkG inkB dab.Alpha
+ for (runX, runY, runW) in VillageArt.ellipseRuns dab.X dab.Y dab.Rx dab.Ry do
+ spriteBatch.Draw(pixel, Rectangle(runX, runY, runW, 1), inkColor)
+
// 标题:淡入 + 上浮,先画深色投影再画亮面。
let titleRise = int (24.0f * (1.0f - reveal))
PixelText.draw spriteBatch pixel cjkAtlas (layout.TitleX + 4) (layout.TitleY + titleRise + 4) layout.TitleScale (Color(12, 20, 28, alpha 255)) LaunchScreen.title