diff options
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/Game.fs | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index 62102a7..a5049f3 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -142,6 +142,9 @@ type LivingVillageGame() as this = let mutable autoplayFrames = 0 let mutable flowStep = 0 let mutable sampleState = SampleScript.initial + let mutable hudClock = 0L + let mutable hudStatus = "" + let mutable hudStatusAt = 0L do graphics.PreferredBackBufferWidth <- 1280 @@ -179,12 +182,12 @@ type LivingVillageGame() as this = member private this.SaveWorld (prefix: string) : bool = try WorldSave.saveToFile savePath world - m5View <- { m5View with Status = "save succeeded" } + m5View <- { m5View with Status = "save succeeded"; StatusTick = Some world.Tick } printfn $"{prefix}=ok path={savePath} tick={world.Tick}" true with | ex -> - m5View <- { m5View with Status = "save failed" } + m5View <- { m5View with Status = "save failed"; StatusTick = Some world.Tick } printfn $"{prefix}=error path={savePath} message={ex.Message}" false @@ -440,6 +443,10 @@ type LivingVillageGame() as this = this.UpdatePlaying gameTime kb pressed pressedAny else this.UpdateMenu pressed + hudClock <- hudClock + 1L + if m5View.Status <> hudStatus then + hudStatus <- m5View.Status + hudStatusAt <- hudClock fpsFrames <- fpsFrames + 1 fpsSeconds <- fpsSeconds + gameTime.ElapsedGameTime.TotalSeconds if fpsSeconds >= 1.0 then @@ -582,23 +589,35 @@ type LivingVillageGame() as this = member private this.DrawM5Overlay() = let viewport = this.GraphicsDevice.Viewport - let panelWidth = min 460 (max 1 (viewport.Width - 32)) - let panelHeight = min 520 (max 1 (viewport.Height - 32)) - let panelX = max 16 (viewport.Width - panelWidth - 16) - let panelY = 16 - let panel = Rectangle(panelX, panelY, panelWidth, panelHeight) - let innerX = panelX + 16 - let innerWidth = panelWidth - 32 let textScale = 2 let lineHeight = 18 - let maxChars = max 1 (innerWidth / (6 * textScale)) - let maxLines = max 1 ((panelHeight - 32) / lineHeight) let profile = M6Presentation.profileAtTick world.Tick - let m6Lines = [ sprintf "时间 %s %s" (M6Presentation.dayNightLabel profile.Mode) (M6Presentation.clockLabel simulationControl) ] - let lines = (m6Lines @ M5Interaction.panelLines world m5View) |> List.truncate maxLines + let timeLine = sprintf "时间 %s %s" (M6Presentation.dayNightLabel profile.Mode) (M6Presentation.clockLabel simulationControl) + let persistentLines = + timeLine :: (m5View.Prompt |> Option.toList) + let dialogueLines = + match m5View.Panel, m5View.Menu with + | DialoguePanel, Some menu -> + menu.Options + |> List.mapi (fun index intent -> sprintf "%d %s" (index + 1) (M5Interaction.intentLine intent)) + |> fun options -> [ sprintf "互动:村民 %d" (M5Interaction.menuNpcNumber menu) ] @ options + | _ -> [] + let statusView = { m5View with StatusTick = Some hudStatusAt } + let statusLine = M5Interaction.transientStatusLine hudClock statusView |> Option.toList + let allLines = persistentLines @ dialogueLines @ statusLine + let panelWidth = min 360 (max 1 (viewport.Width - 32)) + let maxLines = max 1 ((viewport.Height - 48) / lineHeight) + let lines = allLines |> List.truncate maxLines + let panelHeight = lines.Length * lineHeight + 24 + let panelX = 16 + let panelY = max 16 (viewport.Height - panelHeight - 16) + let panel = Rectangle(panelX, panelY, panelWidth, panelHeight) + let innerX = panelX + 12 + let innerWidth = max 1 (panelWidth - 24) + let maxChars = max 1 (innerWidth / (6 * textScale)) spriteBatch.Begin() - spriteBatch.Draw(pixel, panel, Color(15, 19, 25, 220)) - spriteBatch.Draw(pixel, Rectangle(panelX, panelY, panelWidth, 4), Color(92, 180, 190)) + spriteBatch.Draw(pixel, panel, Color(15, 19, 25, 160)) + spriteBatch.Draw(pixel, Rectangle(panelX, panelY, panelWidth, 3), Color(92, 180, 190)) lines |> List.iteri (fun index line -> let visible = if line.Length > maxChars then line.Substring(0, maxChars) else line |
