UI 瀏覽控制器
此頁面將介紹基本概念,說明如何在通用 Windows 平台使用 Windows.Gaming.Input.UINavigationController 和相關 API 設計 UI 瀏覽裝置程式。
閱讀此頁面後,您將瞭解:
- 如何收集已連線 UI 瀏覽裝置及其使用者的清單
- 如何偵測瀏覽裝置已新增或移除
- 如何從一或多個 UI 瀏覽裝置讀取輸入
- 如何將遊戲台和搖桿當作瀏覽裝置使用
UI 瀏覽控制器概觀
幾乎所有遊戲至少都會有一些不同於遊戲場景的使用者介面,有時可能只是遊戲前顯示的功能表,或遊戲內出現的對話。 我們必須讓玩家能使用自選的輸入裝置瀏覽此遊戲 UI,但這同時也會增加開發人員的負擔,因為要針對每種輸入裝置新增特定支援,而且也可能導致遊戲和輸入裝置之間不一致,而使玩家感到困惑。 基於上述原因,我們建立了 UINavigationController API。
UI 瀏覽控制器是「邏輯」輸入設備,用來提供各種「實體」輸入裝置可支援的常見 UI 瀏覽命令詞彙。 UI 瀏覽控制器其實就是另一種形式的實體輸入裝置;我們使用瀏覽裝置參照任何可視為瀏覽控制器的實體輸入裝置。 開發人員針對瀏覽裝置進行程式設計 (而非針對特定的輸入裝置),就能避免支援不同輸入裝置的負擔,且在預設情況下可達一致性。
由於每種輸入裝置支援的控制項數目和種類各有不同,且特定輸入設備可能會支援更豐富的瀏覽命令集,因此瀏覽控制器介面會將詞彙命令分為「必要集合」和「選擇性集合」」;必要集合包含最常見和基本的命令,選擇性集合則包含方便但非必要的命令。 所有瀏覽裝置都須支援必要集合的命令,且可支援所有、部分或不支援選擇性集合的命令。
必要集合
瀏覽裝置必須支援必要集合中的所有瀏覽命令,包括:方向 (上、下、左、右)、檢視、功能表、接受和取消命令。
方向命令專用於單一 UI 元素之間的主要 XY 焦點瀏覽。 檢視和功能表命令適用於顯示遊戲資訊 (通常是暫時性,有時為強制呈現),以及在遊戲和功能表內容之間切換。 接受和取消命令分別適用於肯定式 (是) 和否定式 (否) 回應。
下表摘要說明這些命令及其預定用途,並隨附範例。 | 命令 | 預定用途 | -------:| --------------- | Up | XY 焦點向上瀏覽 | Down | XY 焦點向下瀏覽 | Left | XY 焦點向左瀏覽 | Right | XY 焦點向右瀏覽 | View | 顯示遊戲資訊 (計分板、遊戲統計資料、目標、世界或區域地圖) | Menu | 主要功能表/暫停 (設定、狀態、設備、庫存、暫停) | Accept | 肯定式回應 (接受、繼續、確認、開始、是) | Cancel | 否定式回應 (拒絕、返回、拒絕、停止、否)
選擇性集合
瀏覽裝置也可支援選擇性集合中的所有、部分瀏覽命令,或都不支援;這類命令包括分頁 (上、下、左和右)、捲動 (上、下、左和右) 和關聯式 (context 1-4) 命令。
關聯式命令明確適用於應用程式特定的命令和瀏覽快速鍵。 分頁命令適用於快速瀏覽頁面或不同的 UI 元素群組;捲動命令則適用於 UI 元素內的細項瀏覽。
下表摘要說明這些命令及其預定用途。 | 命令 | 預定用途 | -----------:| ------------ | PageUp | 向上跳頁 (至上方/前一個垂直頁面或群組) | PageDown | 向下跳頁 (至下方/下一個垂直頁面或群組) | PageLeft | 向左跳頁 (至左方/前一個水平頁面或群組) | PageRight | J向右跳頁 (至右方/下一個水平頁面或群組) | ScrollUp | 向上捲動 (在焦點 UI 元素或可捲動的群組內) | ScrollDown | 向下捲動 (在焦點 UI 元素或可捲動的群組內) | ScrollLeft | 向左捲動 (在焦點 UI 元素或可捲動的群組內) | ScrollRight | 向右捲動 (在焦點 UI 元素或可捲動的群組內) | Context1 | 主要內容動作 | Context2 | 次要內容動作 | Context3 | 第三內容動作 | Context4 | 第四內容動作
注意雖然遊戲可回應任何實際用途與預定用途不同的命令,但仍應避免意料之外的行為。 尤其是如果您需要該預定用途,則請勿變更命令的實際函式;請試著將新函式指派給最合理的命令,並將對應函式指派給相應的命令,例如 PageUp/PageDown。 最後,請考慮各種輸入裝置支援的命令及其對應的控制項,確定從每個裝置都能存取重要命令。
遊戲台、搖桿和賽車方向盤瀏覽
Windows.Gaming.Input 命名空間支援的所有輸入裝置都是 UI 瀏覽裝置。
下表摘要說明如何將必要的瀏覽命令集合對應至不同的輸入裝置。
瀏覽命令 | 遊戲台輸入 | 搖桿輸入 | 賽車方向盤輸入 |
---|---|---|---|
Up | 左搖桿向上/方向鍵上 | 搖桿上 | 方向鍵上 |
向下 | 左搖桿向下/方向鍵下 | 搖桿下 | 方向鍵下 |
Left | 左搖桿向左/方向鍵左 | 搖桿左 | 方向盤左 |
Right | 左搖桿向右/方向鍵右 | 搖桿右 | 方向鍵右 |
檢視 | 檢視按鍵 | 檢視按鍵 | 檢視按鍵 |
功能表 | Menu 按鈕 | 功能表按鈕 | Menu 按鈕 |
Accept | A 按鍵 | Action 1 按鍵 | A 按鍵 |
取消 | B 按鍵 | Action 2 按鍵 | B 按鍵 |
下表摘要說明如何將選擇性瀏覽命令集合對應至不同的輸入裝置。
瀏覽命令 | 遊戲台輸入 | 搖桿輸入 | 賽車方向盤輸入 |
---|---|---|---|
PageUp | LT 鍵 | 不支援 | 視情況而異 |
PageDown | 觸發往右 | 不支援 | 視情況而異 |
PageLeft | LB 鍵 | 不支援 | 視情況而異 |
PageRight | RB 鍵 | 不支援 | 視情況而異 |
ScrollUp | 右搖桿向上 | 不支援 | 視情況而異 |
ScrollDown | 右搖桿向下 | 不支援 | 視情況而異 |
ScrollLeft | 右搖桿向左 | 不支援 | 視情況而異 |
ScrollRight | 右搖桿向右 | 不支援 | 視情況而異 |
Context1 | X 按鍵 | 不支援 | X 按鍵 (通常) |
Context2 | Y 按鍵 | 不支援 | Y 按鍵 (通常) |
Context3 | 左搖桿按下 | 不支援 | 視情況而異 |
Context4 | 右搖桿按下 | 不支援 | 視情況而異 |
偵測和追蹤 UI 瀏覽控制器
雖然 UI 瀏覽控制器是邏輯輸入裝置,但代表的是實體裝置,且系統會以相同方式管理該控制器。 您不需要自行建立或初始化;系統會提供已連線 UI 瀏覽控制器和事件的清單,並於新增或移除 UI 瀏覽控制器時通知您。
UI 瀏覽控制器清單
UINavigationController 類別提供靜態屬性 UINavigationControllers,這是目前已連線 UI 瀏覽裝置的唯讀清單。 由於您可能只對某些已連線的瀏覽裝置感興趣,因此建議自行維護裝置集合,不要透過 UINavigationControllers
屬性存取。
下列範例會將所有已連線的 UI 瀏覽控制器複製到新的集合中。
auto myNavigationControllers = ref new Vector<UINavigationController^>();
for (auto device : UINavigationController::UINavigationControllers)
{
// This code assumes that you're interested in all navigation controllers.
myNavigationControllers->Append(device);
}
新增和移除 UI 瀏覽控制器
新增或移除 UI 瀏覽控制器時,會引發 UINavigationControllerAdded 和 UINavigationControllerRemoved 事件。 您可以註冊這些事件的事件處理常式,以追蹤目前連線的瀏覽裝置。
下列範例會開始追蹤已新增的 UI 瀏覽裝置。
UINavigationController::UINavigationControllerAdded += ref new EventHandler<UINavigationController^>(Platform::Object^, UINavigationController^ args)
{
// This code assumes that you're interested in all new navigation controllers.
myNavigationControllers->Append(args);
}
下列範例會停止追蹤已移除的搖桿。
UINavigationController::UINavigationControllerRemoved += ref new EventHandler<UINavigationController^>(Platform::Object^, UINavigationController^ args)
{
unsigned int indexRemoved;
if(myNavigationControllers->IndexOf(args, &indexRemoved))
{
myNavigationControllers->RemoveAt(indexRemoved);
}
}
使用者和耳機
每個瀏覽裝置都可與使用者帳戶建立關聯,以將身分識別連結至輸入,且可使用耳機以利語音交談或瀏覽功能。 若要深入瞭解如何使用使用者和耳機,請參閱<追蹤使用者及其裝置>和>耳機>。
讀取 UI 瀏覽控制器
識別感興趣的 UI 瀏覽裝置後,即可從中收集輸入。 不過,瀏覽裝置不會透過引發事件來傳達狀態變更,可能與您習慣的其他種輸入不同。 不過,您可以透過輪詢的方式,定期讀取裝置的目前狀態。
輪詢 UI 瀏覽控制器
輪詢時,系統會在精確的時間點擷取瀏覽裝置快照。 這種收集輸入命令的方式很適合大部分遊戲,因為該方式的邏輯通常會以決定性迴圈執行,而非事件驅動。而且,比起解讀一段期間收集到的許多單一輸入,針對一次收集到的所有輸入解讀遊戲命令,通常也比較簡單。
您可呼叫 UINavigationController.GetCurrentReading輪詢瀏覽裝置;此函式會傳回包含瀏覽裝置狀態的 UINavigationReading。
auto navigationController = myNavigationControllers[0];
UINavigationReading reading = navigationController->GetCurrentReading();
讀取按鈕
每個 UI 瀏覽按鈕都有布林值讀取值,對應目前是按下 (向下) 或放開 (向上)。 為講求效率,按鍵讀取值不會以個別的布林值表示,而是全都封裝至兩個位元欄位之一,以 RequiredUINavigationButtons 和 OptionalUINavigationButtons 列舉讀取。
屬於必要集合的按鍵是從 UINavigationReading 結構的 RequiredButtons
屬性讀取;屬於選擇性集合的按鍵則是從 OptionalButtons
屬性讀取。 由於這些屬性是位元欄位,因此使用位元遮罩來隔離您有興趣的按鍵值。 如已設定對應位元,按鍵為按下 (向下);反之則為放開 (向上)。
下列範例會判斷必要集合的 [接受] 按鈕是否已按下。
if (RequiredUINavigationButtons::Accept == (reading.RequiredButtons & RequiredUINavigationButtons::Accept))
{
// Accept is pressed
}
下列範例會判斷必要集合的 [接受] 按鈕是否已放開required set。
if (RequiredUINavigationButtons::None == (reading.RequiredButtons & RequiredUINavigationButtons::Accept))
{
// Accept is released (not pressed)
}
讀取選擇性集合的按鈕時,請務必使用 OptionalButtons
屬性和 OptionalUINavigationButtons
列舉。
下列範例會判斷選擇性集合的 [Context 1] 按鍵是否已按下。
if (OptionalUINavigationButtons::Context1 == (reading.OptionalButtons & OptionalUINavigationButtons::Context1))
{
// Context 1 is pressed
}
有時候,您可能會想判斷按鍵的轉換狀態:是從按下到放開、放開到按下,還是有多個已按下或放開的按鍵,或特定的按鍵組合 (有些按下、有些放開)。 如需有關如何偵測這些條件的資訊,請參閱<偵測按鍵轉換>和<偵測複雜的按鍵組合>。
執行 UI 瀏覽控制器範例
InputInterfacingUWP 範例 (github) 示範不同的輸入裝置如何當作 UI 瀏覽控制器使用。
另請參閱
Windows.Gaming.Input.GamepadWindows.Gaming.Input.ArcadeStickWindows.Gaming.Input.RacingWheelWindows.Gaming.Input.IGameController