summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-21 12:07:13 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-21 12:07:13 +0800
commit506afd9e38cad2ab0752734b79ef02da0864db67 (patch)
tree6006269927609e53bfd826df4f6307681f994a0a /src/LivingVillage.Desktop
parent2851a030db0f0bc5892305fb189a41c97c13578d (diff)
downloadliving-village-506afd9e38cad2ab0752734b79ef02da0864db67.tar.gz
fix(desktop): 键位页键名列统一宽度不叠印
Controls 页按键名列独立成列(ControlsKeyX/KeyWidth=120/ActionX),controlRowRects 纯函数返回键名与动作矩形,回归测试断言逐行矩形不相交、全部行键名列 x/宽度一致、列宽容纳最长键名 F1/F2/F3;面板上移至 ControlsPanelY 保证 14 行键位加页脚完整落入视口。
Diffstat (limited to 'src/LivingVillage.Desktop')
-rw-r--r--src/LivingVillage.Desktop/Game.fs6
-rw-r--r--src/LivingVillage.Desktop/TitleScreen.fs21
2 files changed, 24 insertions, 3 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs
index 7337129..25b8c48 100644
--- a/src/LivingVillage.Desktop/Game.fs
+++ b/src/LivingVillage.Desktop/Game.fs
@@ -547,6 +547,8 @@ type LivingVillageGame() as this =
| LoadError -> 4
| Playing -> 0
let rowHeight = if menu.Page = Controls then 25 else layout.MenuLineHeight
+ let panelY =
+ if menu.Page = Controls then layout.ControlsPanelY else layout.PanelY
let panelHeight =
min (height - panelY - 16)
(max layout.PanelHeight (120 + contentRows * rowHeight + 48))
@@ -622,7 +624,9 @@ type LivingVillageGame() as this =
drawText innerX (layout.HeadingY) mutedColor (ChineseText.menuHeading ControlsHeading)
MenuState.controlRows
|> List.iteri (fun index row ->
- drawText innerX (contentY + index * 25) textColor (sprintf "%s %s" row.Keys row.Action))
+ let keyRect, actionRect = TitleScreen.controlRowRects layout index
+ PixelText.draw spriteBatch pixel cjkAtlas keyRect.X keyRect.Y textScale textColor row.Keys
+ PixelText.draw spriteBatch pixel cjkAtlas actionRect.X actionRect.Y textScale textColor row.Action)
drawText innerX (panelY + panelHeight - 40) mutedColor "ESC 返回"
| LoadError ->
drawText innerX (layout.HeadingY) (Color(240, 130, 120)) "读取失败"
diff --git a/src/LivingVillage.Desktop/TitleScreen.fs b/src/LivingVillage.Desktop/TitleScreen.fs
index 00cf5b8..7ec46d2 100644
--- a/src/LivingVillage.Desktop/TitleScreen.fs
+++ b/src/LivingVillage.Desktop/TitleScreen.fs
@@ -29,7 +29,12 @@ module TitleScreen =
FirstItemY: int
CursorX: int
CursorWidth: int
- TextX: int }
+ TextX: int
+ ControlsPanelY: int
+ ControlsRowHeight: int
+ ControlsKeyX: int
+ ControlsKeyWidth: int
+ ControlsActionX: int }
type TextRect =
{ X: int
@@ -43,6 +48,13 @@ module TitleScreen =
|| a.Y + a.Height <= b.Y
|| b.Y + b.Height <= a.Y
+ /// Key-name and action rectangles for one controls-page row. The key column has a
+ /// fixed width shared by every row, so all action texts start on the same x.
+ let controlRowRects (layout: TitleLayout) (rowIndex: int) : TextRect * TextRect =
+ let y = layout.FirstItemY + rowIndex * layout.ControlsRowHeight
+ { X = layout.ControlsKeyX; Y = y; Width = layout.ControlsKeyWidth; Height = 16 },
+ { X = layout.ControlsActionX; Y = y; Width = layout.PanelX + layout.PanelWidth - layout.ControlsActionX - 24; Height = 16 }
+
/// Cursor and label rectangles for one menu row. The cursor is drawn in its own
/// column; the label always starts to the right of it, so they can never overprint.
let selectionRects (layout: TitleLayout) (rowIndex: int) : TextRect * TextRect =
@@ -111,4 +123,9 @@ module TitleScreen =
FirstItemY = height / 2 - 64 + 60
CursorX = (width - panelWidth) / 2 + 24
CursorWidth = 20
- TextX = (width - panelWidth) / 2 + 24 + 20 + 12 }
+ TextX = (width - panelWidth) / 2 + 24 + 20 + 12
+ ControlsPanelY = max 16 (height - 480)
+ ControlsRowHeight = 25
+ ControlsKeyX = (width - panelWidth) / 2 + 24
+ ControlsKeyWidth = 120
+ ControlsActionX = (width - panelWidth) / 2 + 24 + 120 + 12 }