標籤:

淺談鍵盤布局與遊戲 UI 設計(下)

目錄

  • ?1 問題
  • 2 分析
  • 3 物理布局
  • 3.1 鍵盤上究竟有多少鍵

  • 3.2 Windows 新三鍵

  • 3.3 其它造型的 ANSI / ISO 鍵盤

  • 3.4 韓國鍵盤

  • 3.5 日本鍵盤

  • 3.6 巴西鍵盤

  • 3.7不同鍵數鍵盤的兼容性問題
  • 4 遊戲 UI 設計
  • 4.1 目標
  • 4.2 實現
  • 5 總結

?3.7 不同鍵數鍵盤的兼容性問題

先介紹一個總的原則:在 Windows 中,系統通常不會去特意區分不同的物理鍵盤布局

這是因為,鍵盤不過是個非常簡單的硬體設備罷了。它僅有的能力,就是將用戶按下和抬起按鍵的操作,轉換為編碼發送給操作系統*。例如,101/104-鍵鍵盤和 102/105-鍵鍵盤僅有的區別,是前者可以發送按下和抬起0x31 一個鍵的信號,後者可以發送按下和抬起0x32、0x64 兩個鍵的信號。

*其實還有從操作系統接收命令,控制 Caps Lock、Scroll Lock 和 Num Lock 燈亮/滅的能力。這種能力相當於可以向外泄露信息,因此也被用於旁路攻擊。

各種物理鍵盤布局的「鍵數」和自己的「特色鍵」各種物理鍵盤布局的「鍵數」和自己的「特色鍵」

上表列出了各種物理鍵盤布局的「鍵數」和自己的「特色鍵」(均為 Windows 下)。由於系統不會去特意區分物理鍵盤布局,所以如果我們插入了一種鍵盤,卻設置使用了一種不是為該鍵盤的物理布局設計的鍵盤/輸入法的話,最多只是鍵盤上缺的那個鍵,我們無法錄入而已

不過,有兩個鍵是特殊的,在考慮缺鍵的時候不用考慮,那就是 0x31 和 0x32 兩個鍵。這兩個鍵不會出現在同一個鍵盤上,而且它們的位置(在非規範的布局中又往往)互相可替換,因此,實踐中,一般系統實現時都會將 0x31 和 0x32 鍵視作同一個按鍵,映射到軟體鍵盤布局上。

也就是說,如果一個鍵盤布局原本要求你按 0x31 鍵,但是你的鍵盤只有 0x32,沒問題,按它,系統會當作 0x31 鍵。反之,如果一個鍵盤布局原本要求你按 0x32 鍵,但是你的鍵盤只有 0x31,也沒問題,按它,系統會當作 0x32 鍵。

舉個例子。比如,硬體是 ISO 105 鍵盤,卻設置使用了為 101/104-鍵鍵盤設計的鍵盤/輸入法,例如美國鍵盤,理論上不會有任何問題。

硬體為 ISO 105 鍵盤,軟體設置為美國鍵盤布局硬體為 ISO 105 鍵盤,軟體設置為美國鍵盤布局

儘管為 101/104-鍵鍵盤設計的鍵盤/輸入法期望的是回車鍵上方的 0x31 鍵,而你的鍵盤上提供的實際上是回車鍵左邊的 0x32 鍵,但 ?ISO 布局的 0x32 鍵會自動接替 ANSI 布局的 0x31 鍵,起到完全一樣的作用

ISO 布局中左 Shift 鍵右邊的 0x64 鍵因為在 ANSI 鍵盤中不存在,所以按下這個鍵的時候,其實際作用可能和 0x31、0x32 鍵一樣,也可能不一樣或者完全沒有反應。這取決於軟體鍵盤布局如何設計。

總的來說,如果是在 ISO 105 鍵盤上使用為 ANSI 104 鍵盤設計的布局,不會有任何問題。相反,如果硬體是 ANSI 101/104-鍵鍵盤,卻設置使用了為 ISO 102/105-鍵鍵盤設計的鍵盤/輸入法,例如英國鍵盤,就會有問題:

硬體為 ANSI 104 鍵盤,軟體設置為英國鍵盤布局,「反斜杠、豎線」鍵不在了,無法輸入硬體為 ANSI 104 鍵盤,軟體設置為英國鍵盤布局,「反斜杠、豎線」鍵不在了,無法輸入

由於?「反斜杠、豎線」鍵不在了,我們無法輸入命令行操作中兩個至關重要的符號,使用場景會十分受限。這種現象,在老牌歐洲國家很常見。當地ISO 鍵盤占絕對主流,這些鍵盤布局當初為 ISO 鍵盤設計,也沒有理由做後續的更改,因此就一直流傳下來。

相對而言,一些小國家,或者國際影響力沒有那麼大的國家,在設計鍵盤布局標準時,通常就會考慮基於 ANSI 鍵盤設計以減少麻煩。例如,中國直接採用 ANSI 鍵盤與美國鍵盤布局,韓國僅在 ANSI 鍵盤和美國鍵盤布局的基礎上添加了「漢字轉換」和「韓英切換」兩個功能鍵。

在台灣出售的鍵盤除了美國鍵盤布局上面的字,還印了注音符號、倉頡字根和大易字根在台灣出售的鍵盤除了美國鍵盤布局上面的字,還印了注音符號、倉頡字根和大易字根

?或者,也可能採用同時兼顧 ANSI 鍵盤和 ISO 鍵盤的設計,即 ISO 優先,同時用 Alt Gr 照顧 ANSI 鍵盤的情況。例如前文提到過的土耳其語 F-鍵盤:?

儘管土耳其語 F-鍵盤將大於號小於號放在了 0x64  鍵上,它也在旁邊提供了替代方案儘管土耳其語 F-鍵盤將大於號小於號放在了 0x64 鍵上,它也在旁邊提供了替代方案

?儘管土耳其語 F-鍵盤法國鍵盤一樣將大於號、小於號放在了左 Shift 鍵右邊的 0x64 鍵上,它也在旁邊提供了替代方案:Alt Gr + Shift + [J] 可以輸入小於號,Alt Gr + Shift + [?] 可以輸入大於號。0x64 鍵上的另一個符號「豎線」也可以通過 Alt Gr + [-] 來輸入。

0x64 鍵上最後一個符號「斷開的豎線」用 ANSI 鍵盤無法輸入,但這個符號平常基本上用不到,而且也不會在編程語言中出現,所以沒有就沒有吧。總而言之,大多數情況下,缺鍵不會造成完全無法使用,但可能會讓使用場景受限。例如缺少大於號、小於號使得命令行操作難以進行。

巴西鍵盤雖然不是 ISO 鍵盤,但它是基於 ISO 鍵盤設計,並且增加了自己獨佔的按鍵。可能是考慮到自身的國際影響力有限,巴西鍵盤在設計時也貫徹了「基於 ISO 鍵盤,兼顧 ISO 鍵盤」的理念。

沒有 0x87 鍵的 ISO 鍵盤,可以用 Alt Gr 分別加上 Q、W、E 輸入斜杠、問號和度數符號沒有 0x87 鍵的 ISO 鍵盤,可以用 Alt Gr 分別加上 Q、W、E 輸入斜杠、問號和度數符號

?對於沒有右 Shift 鍵左邊的那個 0x87 鍵的 ISO 鍵盤,巴西鍵盤允許用戶用 Alt Gr + [Q]、Alt Gr + [W] 和 Alt Gr + [E] 分別輸入斜杠、問號和度數符號。但是,如果你是用 ANSI 鍵盤的,那就沒辦法了,巴西鍵盤並不提供輸入反斜杠和豎線的替代方案。

微軟韓語輸入法和微軟日語輸入法對鍵盤的兼容性就非常好,二者都只需要 ANSI 鍵盤即可微軟韓語輸入法和微軟日語輸入法對鍵盤的兼容性就非常好,二者都只需要 ANSI 鍵盤即可

?相對來說,微軟韓語輸入法和微軟日語輸入法對鍵盤的兼容性就非常好,二者都只需要 ANSI 鍵盤即可正常使用。不過,別忘了在輸入法的設置里正確選擇 101/102 鍵盤哦。設置之後,韓國鍵盤日本鍵盤上的特殊鍵會全部或部分被 ANSI 鍵盤上就有的鍵取代,以實現正常操作。

了解了各種各樣的鍵盤之後,咱們來看看,怎麼才能在設計遊戲 UI 的時候,讓 UI 更友好,儘可能照顧到更多的玩家呢?

4 遊戲 UI 設計4.1 目標

首先,筆者想說的第一個設計原則是,如果一個遊戲不允許玩家自定義鍵位,就不要使用 ANSI 鍵盤以外的鍵。同時,最好避免使用 0x31(ANSI 鍵盤的「反斜杠、豎線」)或 0x32 (ISO 鍵盤迴車左下方的鍵)這種位置不定的鍵。看一個反面教材:

某日本遊戲使用了大部分鍵盤不存在的「ろ」鍵和位置並不一定在那裡的 0x32 鍵某日本遊戲使用了大部分鍵盤不存在的「ろ」鍵和位置並不一定在那裡的 0x32 鍵

?某日本遊戲使用了大部分鍵盤不存在的「ろ」鍵和位置並不一定在那裡的0x32 鍵。用上「ろ」鍵的那一組操作(ツイスト回転),在大部分鍵盤上就無法正常進行。用上 0x32 鍵的那一組操作(パース変更),在 ANSI 鍵盤上操作起來就會有點彆扭,因為「反斜杠、豎線」鍵離其它鍵很遠。

如果這六個鍵能向左平移一格,兼容性就會好很多,而且不會成為反面教材。

第二個設計原則是,如果允許玩家自定義鍵位,請務必儘可能照顧更多的鍵盤布局的實際情況。例如同樣的釋放終極技能按鍵,《守望先鋒》在美國鍵盤下會顯示 Q,法國鍵盤下會顯示 A,土耳其 F-鍵盤下會顯示 F,照顧到了大多數常用的非 QWERTY 拉丁字母鍵盤。

《守望先鋒》能夠根據當前鍵盤布局自適應顯示正確的字母《守望先鋒》能夠根據當前鍵盤布局自適應顯示正確的字母

?《守望先鋒》不僅能夠在遊戲中的界面根據當前鍵盤布局自適應顯示正確的字母,也可以在鍵位設置界面根據當前鍵盤布局自適應顯示正確的字母。例如,我們將鍵盤布局設置為土耳其 F-鍵盤,然後進入設置界面的話:

將鍵盤布局設置為土耳其 F-鍵盤,然後進入設置界面的話將鍵盤布局設置為土耳其 F-鍵盤,然後進入設置界面的話

?可以看到《守望先鋒》自動以土耳其 F-鍵盤來顯示所有按鍵。不過,這裡有個小錯誤:「向後」和裝填彈藥實際上分別映射到 ? 鍵和 I 鍵(相當於 ANSI 的 S 鍵和 R 鍵),但是在這裡顯示的都是同樣的 I。可能是字體的問題吧?或者是什麼奇怪的 bug。

土耳其 F-鍵盤。WSAD 在這個鍵盤是 G?UE,技能 2 和 3 則是 ? 和 F土耳其 F-鍵盤。WSAD 在這個鍵盤是 G?UE,技能 2 和 3 則是 ? 和 F

?那麼問題來了,我們的遊戲在運行時怎麼才能知道 Windows 系統當前設置的鍵盤/輸入法,以及這個鍵盤/輸入法的實際布局呢?

4.2 實現

?筆者首先想到的是 C# 的 CultureInfo 類,但是失敗了。

筆者猜測 CurrentCulture 返回的是區域與語言選項里的格式設置筆者猜測 CurrentCulture 返回的是區域與語言選項里的格式設置

?在筆者實測中,無論筆者怎麼切換輸入法,CultureInfo 類的CurrentCulture 總是返回「中文(中國)」。猜測:它返回的是區域與語言選項里的格式設置。?未經證實,請勿輕信,總之不能用。

筆者猜測 CurrentUICulture 返回的是語言選項里的 Windows 顯示語言筆者猜測 CurrentUICulture 返回的是語言選項里的 Windows 顯示語言

?Cul?tureInfo 的另一個 property,CurrentUICulture,無論筆者怎麼切換輸入法,總是返回「英語(美國)」。猜測:它返回的是語言選項里的 Windows 顯示語言。?同樣未經證實,請勿輕信,總之也不能用。

用 Google 搜索之後,發現https://yal.cc/csharp-get-current-keyboard-layout/提到一種用 Windows API 獲取當前鍵盤布局的方法。經過實測,這種方法也對,也不對。

?對的地方是 Windows 的 GetKeyboardLayout 函數確實可以獲取鍵盤布局,但是原作者在後面 AND 了個 0xFFFF 是不對的。

原作者在後面 AND 了個 0xFFFF 是不對的原作者在後面 AND 了個 0xFFFF 是不對的

?GetKeyboardLayout 函數的返回值是 32 位整數,低 16 位表示的是當前語言,也就是「英語(美國)」?、「中文(中國)」這樣的。例如當前鍵盤/輸入法為土耳其語 Q-鍵盤土耳其語 F-鍵盤時,GetKeyboardLayout 函數的返回值分別為 0x041f041f 和 0xf014041f,低 16 位是相同的。

因此,如果用 AND 0xFFFF 取低 16 位的話,只能精確到當前語言,無法獲得到具體的鍵盤布局。對於鍵盤布局單一的語言,可能問題不大。但對於?有多種鍵盤布局的語言(如土耳其語有 Q-鍵盤和 F-鍵盤),只看低 16 位就不靠譜了。正確的代碼應該是用如下代碼取高 16 位即可:

int keyboardLayout = (GetKeyboardLayout(foregroundProcess).ToInt32() >> 16) & 0xFFFF;

實測,試了一些不同的鍵盤布局,高 16 位都不一樣。如果不放心,可以用整個 32 位整數做判斷,肯定不會錯,而且還能減少位移運算和按位與運算

?需要指出的是,這個函數只能獲取鍵盤布局,不能獲取輸入法。也就是說,如果你把當前語言切換到中日韓等使用輸入法而非鍵盤布局的語言,這個函數總會返回與輸入法無關的結果。例如,當前輸入法是搜狗拼音 / 微軟拼音,函數的返回值都是 0x08040804。但這已經足夠滿足我們的需求。

還有一個可以改進的地方是,原作者的代碼是獲取用戶正在操作的窗口(foreground window)而不是獲取自己的窗口。?如果原作者的目的是實現一個屏顯虛擬鍵盤,那麼獲取用戶正在操作的窗口的鍵盤布局是沒錯的。

但是,我們的目標如果只是在遊戲中正常顯示按鍵的話,可以只獲取當前窗口的鍵盤布局。方法是,把 GetForegroundWindow 函數調用去掉,直接寫:

uintforegroundProcess = GetWindowThreadProcessId(IntPtr.Zero, IntPtr.Zero);

?即可獲得自己的窗口的鍵盤布局。

獲取到鍵盤布局之後,筆者遇到了一個新問題:沒有找到從 Windows 系統直接獲取鍵盤布局上每一個鍵是什麼內容的函數。這樣的函數應該是存在的,因為 Microsoft Keyboard Layout Creator 就有這個從系統中讀取現有的鍵盤布局並加以編輯的功能。

MSKLC 能夠直接載入系統中已有的鍵盤布局,說明這樣的函數肯定存在MSKLC 能夠直接載入系統中已有的鍵盤布局,說明這樣的函數肯定存在

?不過,貌似暴雪也沒有從系統獲取鍵盤布局的內容。暴雪似乎是在遊戲中內置了若干常用鍵盤布局備用。因為,當我們設置一些非常罕見的鍵盤(比如亞塞拜然鍵盤)時,《守望先鋒》就無法辨識它,並且依然按照 QWERTY 來顯示各個鍵位的字元。?

《守望先鋒》不能識別亞塞拜然鍵盤,但 MSKLC 可以正常讀取《守望先鋒》不能識別亞塞拜然鍵盤,但 MSKLC 可以正常讀取

事實上,有的時候直接從 Windows 載入鍵盤布局也不一定是特別好的方法。比如印度鍵盤,直接買來可能是這個樣子的:?

印刷有天城文的印度鍵盤印刷有天城文的印度鍵盤

?對於這種鍵盤,如果直接像 MSKLC 那樣從系統讀取鍵盤布局的話,讀出來的就不是拉丁字母,而是天城文了。遊戲要面對正確顯示天城文的問題,這可不是一件簡單的事情,吃力不討好。不如,直接按照 ANSI 鍵盤顯示英文字母和符號,只要玩家低頭看鍵盤能找到那個字母,就萬事 OK。

可能這也是暴雪要自己在遊戲里維護一份鍵盤布局來顯示的原因吧。所以,就這樣吧。這個探索就到此為止了。

簡單來說,關於這個問題,筆者的建議是,找一些常用的鍵盤布局,加到遊戲里,支持正常顯示它們就可以了。

另一方面,即使真的能找到 Windows 里載入鍵盤布局內容的函數,也因為要顯示多種文字存在技術問題,筆者並不推薦直接將布局內容在遊戲中顯示出來。函數獲取的內容最好是作為開發者維護遊戲中的鍵盤布局的一個輔助工具,例如讀出亞塞拜然鍵盤並加到遊戲里,供後續正常顯示即可。?

?5 總結

1、不同的物理鍵盤布局有很多種。常見的有? ANSI(101/104-鍵)、ISO(102/105-鍵)、韓國(103/106-鍵)、日本(106/109-鍵)、巴西(104/107-鍵)。均為 Windows 鍵盤的布局。

常見的鍵盤物理布局。0x31 個 0x32 被系統視作同一按鍵常見的鍵盤物理布局。0x31 個 0x32 被系統視作同一按鍵

?2、設計交互時,應避免使用 ANSI 鍵盤上沒有的按鍵。?

3、由於每個按鍵的實際作用是硬體和軟體共同決定的,因此,如果允許用戶自定義鍵位,?遊戲應當獲取系統當前的鍵盤布局,並根據鍵盤布局顯示按鍵上正確的字元


?轉發抽獎

?開獎時間:2018 年 6 月 19 日(星期二)晚上見機行事

活動獎品:ARMS T恤×1、超級馬力歐奧德賽帽子×1(來自去年 E3 2017 的任天堂展台)

ARMS T恤和超級馬力歐奧德賽帽子ARMS T恤和超級馬力歐奧德賽帽子

?參與方式:關注筆者 @認真的吉吉,轉發活動微博即可參加抽獎。抽獎時我會抽取 1 名中獎者,獲得來自 E3 2017 任天堂展台的 ARMS T恤一件,以及馬力歐奧德賽帽子一頂。帽子因為我稍微戴過一會兒,如果您不想要,中獎後請務必告知我,我就不發了。

參與規則

  1. 中獎者不能是非正常用戶,如抽獎機器人、專業營銷號等。正常與否以我主觀判定為準。

  2. 如果翻閱中獎者微博時,發現其支持或隸屬於被中國大陸法律法規判定為非法的組織,取消中獎資格。
  3. 如果翻閱中獎者微博時,發現其支持仇恨、歧視、反人類等極端理念,或隸屬於宣揚、鼓勵及實行此類理念的組織,取消中獎資格。?

更多近期文章

關於 PS5、PSV、PS1 和 PS2 的一點想法(2018-05-26)

你們要的實錘,來了(2018-05-19)

淺談鍵盤布局與遊戲 UI 設計(中)(2018-05-04)

淺談鍵盤布局與遊戲 UI 設計(上)(2018-04-27)

Nintendo Switch:繼往開來的變革之作(15)(2018-04-20)

TAG: |