summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/Game.fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
-rw-r--r--src/LivingVillage.Desktop/Game.fs97
1 files changed, 64 insertions, 33 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs
index c6408aa..77fa314 100644
--- a/src/LivingVillage.Desktop/Game.fs
+++ b/src/LivingVillage.Desktop/Game.fs
@@ -3346,16 +3346,16 @@ type LivingVillageGame() as this =
let lx = layout.X
let ly = layout.Y
spriteBatch.Begin()
- // 完整背景框:上下两段半透明深色渐变 + 四边细边框 + 顶部强调线。
- spriteBatch.Draw(pixel, Rectangle(lx, ly, layout.Width, layout.Height / 2), Color(30, 44, 52, 224))
+ // P76:对话面板改与顶部/底部条同语言——半透明底 + 1px 描边 + 发丝强调线,避免大黑块。
+ spriteBatch.Draw(pixel, Rectangle(lx, ly, layout.Width, layout.Height / 2), Color(46, 60, 70, 200))
spriteBatch.Draw(
pixel,
Rectangle(lx, ly + layout.Height / 2, layout.Width, layout.Height - layout.Height / 2),
- Color(14, 22, 30, 232))
- spriteBatch.Draw(pixel, Rectangle(lx, ly, layout.Width, 3), palette.Accent)
- spriteBatch.Draw(pixel, Rectangle(lx, ly + layout.Height - 2, layout.Width, 2), palette.Outline)
- spriteBatch.Draw(pixel, Rectangle(lx, ly, 2, layout.Height), palette.Outline)
- spriteBatch.Draw(pixel, Rectangle(lx + layout.Width - 2, ly, 2, layout.Height), palette.Outline)
+ Color(30, 42, 52, 210))
+ spriteBatch.Draw(pixel, Rectangle(lx, ly, layout.Width, 1), palette.Accent)
+ spriteBatch.Draw(pixel, Rectangle(lx, ly + layout.Height - 1, layout.Width, 1), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(lx, ly, 1, layout.Height), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(lx + layout.Width - 1, ly, 1, layout.Height), palette.Outline)
// 头像:原创 8x16 点阵 @ scale 4 = 32x64,加内框。
if model.ShowAvatar then
let avatar = DialogOverlay.avatarRect layout
@@ -3513,27 +3513,54 @@ type LivingVillageGame() as this =
let palette = HudLayout.palette profile.Mode
let bar = HudLayout.hotbarBarRect viewport.Width viewport.Height
spriteBatch.Begin()
+ // P76:底部条改为与顶部条同语言的紧凑半透明药丸——细描边 + 1px 发丝线,不再铺大色块。
spriteBatch.Draw(pixel, bar, palette.SegmentBackdrop)
- spriteBatch.Draw(pixel, Rectangle(bar.X, bar.Y, bar.Width, 2), palette.Accent)
- spriteBatch.Draw(pixel, Rectangle(bar.X, bar.Bottom - 2, bar.Width, 2), palette.Outline)
- spriteBatch.Draw(pixel, Rectangle(bar.X, bar.Y, 2, bar.Height), palette.Outline)
- spriteBatch.Draw(pixel, Rectangle(bar.Right - 2, bar.Y, 2, bar.Height), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(bar.X, bar.Y, bar.Width, 1), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(bar.X, bar.Bottom - 1, bar.Width, 1), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(bar.X, bar.Y, 1, bar.Height), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(bar.Right - 1, bar.Y, 1, bar.Height), palette.Outline)
+ spriteBatch.Draw(pixel, HudLayout.hotbarBarHairline bar, palette.Accent)
for index in 0 .. HudLayout.hotbarSlotCount - 1 do
let slot = HudLayout.hotbarSlotRect viewport.Width viewport.Height index
let selected = index = hotbarSelected
- let slotBackdrop =
- if selected then Color(48, 66, 74, 210) else palette.SegmentBackdrop
- spriteBatch.Draw(pixel, slot, slotBackdrop)
+ // 槽位药丸:半透明底(选中略亮),1px 描边 + 发丝线,不再是实心大色块。
+ let slotFill =
+ if selected then Color(48, 66, 74, 170) else palette.SegmentBackdrop
+ spriteBatch.Draw(pixel, slot, slotFill)
let border = if selected then palette.Accent else palette.Outline
- spriteBatch.Draw(pixel, Rectangle(slot.X, slot.Y, slot.Width, 2), border)
- spriteBatch.Draw(pixel, Rectangle(slot.X, slot.Bottom - 2, slot.Width, 2), border)
- spriteBatch.Draw(pixel, Rectangle(slot.X, slot.Y, 2, slot.Height), border)
- spriteBatch.Draw(pixel, Rectangle(slot.Right - 2, slot.Y, 2, slot.Height), border)
- let iconRect = HudLayout.hotbarIconRect slot
+ spriteBatch.Draw(pixel, Rectangle(slot.X, slot.Y, slot.Width, 1), border)
+ spriteBatch.Draw(pixel, Rectangle(slot.X, slot.Bottom - 1, slot.Width, 1), border)
+ spriteBatch.Draw(pixel, Rectangle(slot.X, slot.Y, 1, slot.Height), border)
+ spriteBatch.Draw(pixel, Rectangle(slot.Right - 1, slot.Y, 1, slot.Height), border)
+ if selected then
+ spriteBatch.Draw(pixel, Rectangle(slot.X + 1, slot.Y + slot.Height - 2, max 1 (slot.Width - 2), 1), palette.Accent)
+ // 键位符号小片 + 图形并排(P76 信息层次)。
+ let keyChip = HudLayout.hotbarKeyChipRect slot
+ spriteBatch.Draw(pixel, keyChip, palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(keyChip.X + 1, keyChip.Y + 1, max 1 (keyChip.Width - 2), max 1 (keyChip.Height - 2)), Color(18, 28, 34, 220))
+ let label = if index = 9 then "0" else string (index + 1)
+ PixelText.draw spriteBatch pixel cjkAtlas (keyChip.X + 3) (keyChip.Y + 2) 1 (if selected then palette.Accent else palette.Label) label
+ let iconRect = HudLayout.hotbarIconRectBesideKey slot
let iconColor = if selected then palette.Accent else palette.Value
this.DrawPattern (HudLayout.hotbarIconRows index) iconRect.X iconRect.Y HudLayout.hotbarIconScale iconColor
- let label = if index = 9 then "0" else string (index + 1)
- PixelText.draw spriteBatch pixel cjkAtlas (slot.X + 3) (slot.Y + 2) 1 (if selected then palette.Accent else palette.Label) label
+ // 图例:真实按键 + 动作名并排(取自 MenuState.controlRows,纯展示,不改任何绑定)。
+ let legend = HudLayout.actionLegend MenuState.controlRows
+ if not legend.IsEmpty then
+ let legendText = legend |> List.map (fun row -> sprintf "%s %s" row.Keys row.Action) |> String.concat " "
+ let scale = HudLayout.textScale
+ let textWidth = FloatingPrompt.measureWidth legendText scale
+ let legendHeight = 8 * scale + 12
+ let legendWidth = textWidth + 20
+ let legendX = (viewport.Width - legendWidth) / 2
+ let legendY = bar.Y - legendHeight - 6
+ spriteBatch.Draw(pixel, Rectangle(legendX, legendY, legendWidth, legendHeight), palette.SegmentBackdrop)
+ spriteBatch.Draw(pixel, Rectangle(legendX, legendY, legendWidth, 1), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(legendX, legendY + legendHeight - 1, legendWidth, 1), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(legendX, legendY, 1, legendHeight), palette.Outline)
+ spriteBatch.Draw(pixel, Rectangle(legendX + legendWidth - 1, legendY, 1, legendHeight), palette.Outline)
+ for (dx, dy) in HudLayout.textOutlineOffsets do
+ PixelText.draw spriteBatch pixel cjkAtlas (legendX + 10 + dx) (legendY + 6 + dy) scale palette.Outline legendText
+ PixelText.draw spriteBatch pixel cjkAtlas (legendX + 10) (legendY + 6) scale palette.Value legendText
spriteBatch.End()
/// 常驻情境状态:顶部条下方的小药丸,仅 WorldPanel 且瞬态未过期时出现。
@@ -3560,23 +3587,27 @@ type LivingVillageGame() as this =
let lineHeight = 18
let lines = M5Interaction.panelLines world m5View
let panelWidth = min 380 (max 1 (viewport.Width - 32))
- let maxLines = max 1 ((viewport.Height - HudLayout.barHeight - 48) / lineHeight)
- let visibleLines = lines |> List.truncate maxLines
- let panelHeight = visibleLines.Length * lineHeight + 26
let panelX = 16
- let panelY = max (HudLayout.barHeight + 12) (viewport.Height - panelHeight - 16)
let innerX = panelX + 12
let innerWidth = max 1 (panelWidth - 24)
- let maxChars = max 1 (innerWidth / (6 * textScale))
+ // P76:按实测像素宽度折行(中文逐字),换行而非整行截断;不再 Substring 截断。
+ let wrapped = HudLayout.wrapLines innerWidth textScale lines
+ let maxLines = max 1 ((viewport.Height - HudLayout.barHeight - 48) / lineHeight)
+ let visibleLines = wrapped |> List.truncate maxLines
+ let panelHeight = visibleLines.Length * lineHeight + 26
+ let panelY = max (HudLayout.barHeight + 12) (viewport.Height - panelHeight - 16)
spriteBatch.Begin()
- // 竖向渐变板(半透明,非纯黑),顶部与左侧各一条强调线。
- spriteBatch.Draw(pixel, Rectangle(panelX, panelY, panelWidth, panelHeight / 2), Color(30, 44, 52, 190))
- spriteBatch.Draw(pixel, Rectangle(panelX, panelY + panelHeight / 2, panelWidth, panelHeight - panelHeight / 2), Color(16, 24, 30, 190))
- spriteBatch.Draw(pixel, Rectangle(panelX, panelY, panelWidth, 3), Color(92, 180, 190))
- spriteBatch.Draw(pixel, Rectangle(panelX, panelY, 2, panelHeight), Color(92, 180, 190, 160))
+ // 半透明圆角感面板:细描边 + 1px 发丝线(与 P75/P76 同语言),非大色块/纯黑。
+ spriteBatch.Draw(pixel, Rectangle(panelX, panelY, panelWidth, panelHeight / 2), Color(38, 52, 62, 175))
+ spriteBatch.Draw(pixel, Rectangle(panelX, panelY + panelHeight / 2, panelWidth, panelHeight - panelHeight / 2), Color(26, 38, 48, 180))
+ spriteBatch.Draw(pixel, Rectangle(panelX, panelY, panelWidth, 1), Color(92, 180, 190))
+ spriteBatch.Draw(pixel, Rectangle(panelX, panelY, 1, panelHeight), Color(92, 180, 190, 180))
+ spriteBatch.Draw(pixel, Rectangle(panelX, panelY + panelHeight - 1, panelWidth, 1), Color(8, 14, 20, 200))
+ spriteBatch.Draw(pixel, Rectangle(panelX + panelWidth - 1, panelY, 1, panelHeight), Color(8, 14, 20, 200))
visibleLines
|> List.iteri (fun index line ->
- let visible = if line.Length > maxChars then line.Substring(0, maxChars) else line
let color = if index = 0 then Color(226, 238, 226) else Color(192, 208, 212)
- PixelText.draw spriteBatch pixel cjkAtlas innerX (panelY + 13 + index * lineHeight) textScale color visible)
+ for (dx, dy) in HudLayout.textOutlineOffsets do
+ PixelText.draw spriteBatch pixel cjkAtlas (innerX + dx) (panelY + 13 + index * lineHeight + dy) textScale (Color(6, 10, 14)) line
+ PixelText.draw spriteBatch pixel cjkAtlas innerX (panelY + 13 + index * lineHeight) textScale color line)
spriteBatch.End()