gohud

HUD

← 控制項

好不好看,是那些小地方決定的

大面板再怎麼磨,抓住視線的永遠是某個小東西:一個被切成兩半的字、一圈被削掉的光暈、 一格擠成一團的快捷格。2026-09-13 有人指出四件這樣的事,修正做在控制項與佈景主題裡, 而不是示範畫面裡,所以每一個畫面都得到同樣的結果。

看到什麼原因修法
導覽標記的 Done 變成 Don/e 開了換行的按鈕會從最小寬度中扣掉文字寬度 — 一被擠壓就從字中間斷開 GoStyle.fit_words():單一個字永遠不換行;多個字可以換行,但最長的那個字一定塞得下 — 判斷依據是實際顯示的文字,而不是翻譯鍵,而且語言變更時表單會重新套用
整行寬的按鈕,左側的光暈在垂直方向被切掉 捲動容器一律在自己的邊緣裁切,沒有例外。只有右側因為捲軸留出的溝槽而倖免 GoScroll 借用上層的內距,把自己的邊緣往外推 12dp,再在內側還回去 — 內容原地不動
時間、圖示與數量在一格快捷格裡上下堆成三層 48dp 裡塞了三列 圖示放大置中,快速鍵在左上,數量當成右下的徽章,剩餘時間則是壓在圖示上的徽章 — 徽章面板來自外觀的 badge_box()
下拉選單很平,看不出選了哪一個 項目的滑過狀態用的是按鈕面板;選項記號則是引擎那個很淡的預設圖案 專用的滑過面板(柔和的強調色著色)、與核取方塊相同的選項圖案,以及為觸控加高的項目高度
展開的下拉選單 — 柔和的強調色滑過面板,以及被選中項目的選項記號
下拉選單 — 滑過面板與選項記號
四格快捷格 — 快速鍵在左上、數量徽章在右下,第一格還有剩餘時間徽章
快捷格 — 角落徽章與剩餘時間(科幻)

GoStyle.icon_button(icon, action, -1, tooltip_key) 給只有圖示的按鈕一段說明 — 給滑鼠使用者的工具提示,和給螢幕閱讀器的無障礙名稱,都來自這同一個值。 工具提示是 gohud 自己畫的:引擎預設的那個在寬度計算出錯時,會把文字拆成一行一個字 (實測寬度只有 1dp)。

導覽標記的卡片會避開固定元素

橫向時,這張卡片以前會被送到畫面最上或最下的邊緣 — 那裡剛好就是頁首與 HUD 零件的地盤;在示範裡,它就壓在頁首的 → × 上。現在它會與目標保持齊高, 繞開任何有保留空間的 GoHudAnchor,也可以透過 keep_clear 告訴它還要避開什麼。它會用最短的距離移開障礙物,同時不遮住目標; 當螢幕小到怎麼挪都躲不掉時,它就留在原地 — 重疊總比消失好。 它的層次感 — 讓它讀起來像在頁面之上 — 來自外觀的旋鈕 (float_shadow_sizefloat_shadow_liftfloat_shadow_alpha;切角風格的外觀則用 float_glow_size)。

tour.keep_clear = [header_bar, toolbar]   # 不是錨點的固定元素

有滑鼠與鍵盤的畫面

手指沒有滑過狀態。只照著行動裝置開發,就會有兩個只出現在桌機的狀態沒被檢查 — 而其中一個確實壞了:gohud 的焦點外框在主要按鈕上是看不見的。面板是強調色, 外框也是同一個色:1.00:1,等於把同樣的顏色畫在自己身上。 用鍵盤移動時,根本看不出自己在哪裡。

同一列按鈕的三種狀態 — 一般、滑鼠滑過、鍵盤焦點
由上到下:一般 · 滑過 · 焦點。實心按鈕會得到一圈與自己面板形成對比的外框。

實心按鈕(GoPrimaryButtonGoDangerSolidButton)使用的外框 與自己的面板形成對比 — 深色佈景主題上用深色,淺色上用白色,科幻風格則是深色的 瞄準框角。對比檢查器量的是焦點外框與它所在的面板,所以換了調色盤這條規則依然成立 (WCAG 2.4.11 要求焦點指示器達到 3:1)。

HUD 控制項

GoHudAnchor — 九個位置

它會尊重安全區域與邊界留白。給它一個 landscape_spot,橫向時它就會換位置 — 直向時待在底部中央的操作鍵,橫向可以改到右下。

它為什麼存在。每個 HUD 零件各自手寫錨點與位移,數值就會慢慢走樣: 在有瀏海的裝置上,生命量條跑到相機開孔底下;橫向時,操作按鈕落在手勢列上。 那些算式只住在一個地方。

別讓內容跑到 HUD 底下

當一個會捲動的畫面和 HUD 共用螢幕時,內容會滑到它下面,兩邊的文字互相重疊, 最後誰都讀不出來。這在這個附加元件裡發生過兩次:輸入欄的提示文字被擠在快捷格中間, 以及設定裡的切換開關的旋鈕落在生命量條上。

form.avoid_hud = true                  # 避開每一個顯示中的 GoHudAnchor
joystick_anchor.reserve_space = false  # …但只在手指底下才出現的那些除外

每個矩形都往損失面積最小的方向避開。右上角的量條,在直向手機上往下繞 (高度的 13%),在橫向則往側邊繞(寬度的 21%) — 橫向時若改成垂直避開,會吃掉螢幕的 27%。 已經讓出去的地盤,會先扣掉,再去量下一個矩形。

HUD 零件彼此也會撞在一起

九個位置只是把畫面分好;它們並不保證零件彼此不相碰。一條很寬的訊息條擺在 上方中央,就正好壓在右上的生命量條上,把數值遮住 — 你根本讀不到還剩多少血。

notice_anchor.avoid_peers = true      # 停在固定 HUD 下方
notice_anchor.reserve_space = false   # 顯示期間也不會推擠頁面

只在垂直方向讓開 — 連橫向也一起挪的話,置中的提示訊息每次出現的位置就不一樣。 而且它只避開那些本身不會讓開的零件:如果雙方都讓,兩者就會永遠交換位置。

GoBar — 生命、魔力、經驗

var hp := GoBar.new()
hp.label_text = "HP"
hp.ink = GoUi.color(GoTheme.DANGER_FILL)   # 只用於填色的 token
hp.set_values(320, 500)                     # "320 / 500"

數值變化會在 0.18 秒內緩動 — 一條直接跳掉的生命量條,說不出你被打得多重。 reduce_motion 會讓它立即完成。大數字會縮寫成 12.3k, 讓量條的寬度不會隨著位數增減而抖動。

GoSlot — 一格快捷格

圖示、數量、冷卻與快速鍵都在同一個面上。把徽章掛在小圓圈外面, 會讓每一格寬度都不一樣,整列就歪歪扭扭。

看得到的尺寸和按得到的尺寸不同。擠在一起的快捷格,48dp 的觸控範圍會互相重疊; 重疊的部分歸中心比較近的那一格 — 用 touch_peers 讓它們知道彼此的存在。

keyboard_focus 預設是關的,這樣八格一列的快捷格才不會卡在鍵盤使用者與 Tab 順序上 所有設定控制項之間。只有在鍵盤或遊戲手把是唯一輸入方式時才打開它。

GoJoystick — 虛擬搖桿

模式行為
FIXED永遠在同一個地方 — 不用看也找得到
FOLLOW出現在拇指按下的位置
RELATIVE出現之後繼續跟著拇指 — 長時間移動比較舒服

moved 傳出來的 Vector2 長度介於 0–1,所以可以直接乘上速度; 它不會隨螢幕大小或 DPI 改變。

GoIconButton — 看起來小,按起來大

只有在旁邊的兄弟節點不吃輸入時才安全。如果被放大的區域蓋到隔壁按鈕, 那顆按鈕就沒反應了。並排的圖示按鈕需要 touch_peers