> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GameInput 讀數

> GameInput 讀數

<a id="introductionSection" />

從每個裝置接收的原始輸入封包都會封裝在「讀數」物件中。讀數包含原始封包資料，以及 (通常) 一或多個將原始資料轉換為較高階格式的結果。除了作為資料容器之外，讀數也可作為參考輸入串流中特定位置的識別碼。

<a id="acquisitionSection" />

## 取得讀數

GameInput API 提供兩種取得讀數的方式。最常見的方式是透過 [IGameInput](/zh-TW/reference/input/gameinput/interfaces/igameinput/igameinput) 介面上的方法，直接從輸入串流存取讀數。

```c++ theme={null}
HRESULT GetCurrentReading(
    _In_ GameInputKind inputKind,
    _In_opt_ IGameInputDevice * device,
    _COM_Outptr_ IGameInputReading ** reading);
```

呼叫 [GetCurrentReading](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_getcurrentreading) 會從輸入串流擷取最新的讀數。您可以傳入選擇性的 [GameInputKind](/zh-TW/reference/input/gameinput/enums/gameinputkind) 篩選條件，將傳回的讀數限制為特定類型的輸入，例如遊戲台或鍵盤。您也可以傳入選擇性的 [IGameInputDevice](/zh-TW/reference/input/gameinput/interfaces/igameinputdevice/igameinputdevice) 篩選條件，將傳回的讀數限制為僅由指定裝置產生的讀數。這些篩選條件可以個別套用或一起套用。

[IGameInputReading](/zh-TW/reference/input/gameinput/interfaces/igameinputreading/igameinputreading) 執行個體是參考計數的單一物件。擷取讀數是極快速且輕量的作業，不會執行任何記憶體配置或複製，且 API 呼叫是無鎖定的，沒有核心模式轉換。由於讀數是單一物件，應用程式可以比較讀數指標是否相等，以判斷兩次呼叫 [GetCurrentReading](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_getcurrentreading) 是否傳回相同的讀數 (表示未產生新的輸入)。

輸入需求較不複雜的遊戲可能只需每個畫面輪詢一次新的輸入，並比較兩個讀數中儲存的狀態是否有差異 (如果它們不是相同的讀數)。不過，輸入需求較複雜的遊戲可能需要逐步查看輸入串流，以全面了解自上一個畫面以來發生的所有輸入狀態變更。這可透過 [GetNextReading](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_getnextreading) 和 [GetPreviousReading](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_getpreviousreading) 方法達成，這些方法允許與 [GetCurrentReading](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_getcurrentreading) 相同的篩選條件。輸入串流會在其緩衝區中保留過去半秒的歷程讀數。

```c++ theme={null}
HRESULT GetNextReading(
    _In_ IGameInputReading * referenceReading,
    _In_ GameInputKind inputKind,
    _In_opt_ IGameInputDevice * device,
    _COM_Outptr_ IGameInputReading ** reading);

HRESULT GetPreviousReading(
    _In_ IGameInputReading * referenceReading,
    _In_ GameInputKind inputKind,
    _In_opt_ IGameInputDevice * device,
    _COM_Outptr_ IGameInputReading ** reading);
```

或者，應用程式可以註冊在產生輸入時叫用的回呼。與前述的同步方法一樣，可以套用數個篩選條件來控制傳回哪些類型的讀數，以及來自哪些裝置。如需詳細資訊，請參閱進階 GameInput 主題一節中的 [GameInput 回呼](/zh-TW/build/core-features/common/input/advanced/input-callbacks)。

<a id="gettingStateSection" />

## 從讀數取得資料

雖然每個讀數都包含來自裝置的原始輸入封包資料，但讀數通常也包含該資料的一或多個高階轉換結果。例如，從遊戲台接收的輸入也會剖析為具有已知按鈕和搖桿識別碼的標準固定格式結構。讀數通常包含相同原始輸入資料的數種不同表示法，讓應用程式可以選擇最符合其需求的格式。

應用程式可以呼叫讀數的 [GetInputKind](/zh-TW/reference/input/gameinput/interfaces/igameinputreading/methods/igameinputreading_getinputkind) 方法，查詢讀數包含哪些類型的資料。這會從 [GameInputKind](/zh-TW/reference/input/gameinput/enums/gameinputkind) 列舉傳回一或多個旗標值。

```c++ theme={null}
typedef enum GameInputKind
{
    GameInputKindUnknown         = 0x00000000,
    GameInputKindRawDeviceReport = 0x00000001,
    GameInputKindController      = 0x00000002,
    GameInputKindKeyboard        = 0x00000004,
    GameInputKindMouse           = 0x00000008,
    GameInputKindTouch           = 0x00000100,
    GameInputKindMotion          = 0x00001000,
    GameInputKindArcadeStick     = 0x00010000,
    GameInputKindFlightStick     = 0x00020000,
    GameInputKindGamepad         = 0x00040000,
    GameInputKindRacingWheel     = 0x00080000,
    GameInputKindUiNavigation    = 0x01000000
} GameInputKind;
```

讀數中可用的資料類型取決於輸入裝置及其實體屬性。例如，來自標準鍵盤的讀數可能只包含鍵盤資料，而來自內建軌跡球之鍵盤的讀數可能同時包含鍵盤和滑鼠資料。

幾乎所有遊戲控制器產生的讀數都包含一般「控制器」資料，這只是匿名軸和按鈕狀態的集合。這讓具有輸入對應 UI 的應用程式能夠廣泛支援裝置。不過，許多遊戲控制器 (例如遊戲台) 也會在其讀數中公開熟悉的固定格式狀態，讓一般遊戲更容易使用。

```c++ theme={null}
typedef struct GameInputGamepadState
{
    GameInputGamepadButtons buttons;
    float leftTrigger;
    float rightTrigger;
    float leftThumbstickX;
    float leftThumbstickY;
    float rightThumbstickX;
    float rightThumbstickY;
} GameInputGamepadState;
```

[IGameInputReading](/zh-TW/reference/input/gameinput/interfaces/igameinputreading/igameinputreading) 介面包含以讀數支援的任何格式擷取狀態的方法。讀數提供的所有不同表示法都是預先計算的，因此這些方法只會複製幾個位元組的資料並傳回。

<a id="sampleSection" />

## 簡單的遊戲台輸入迴圈

下列範例程式碼是遊戲台完整運作輸入迴圈的一個範例。此範例值得注意的一點是，沒有明確的裝置列舉。[IGameInputDevice](/zh-TW/reference/input/gameinput/interfaces/igameinputdevice/igameinputdevice) 的唯一用途是作為裝置識別碼，從未呼叫其任何方法。這說明了 GameInput API 以輸入為中心的本質，以及它如何簡化常見輸入案例的程式碼。

```c++ theme={null}
IGameInput* g_gameInput = nullptr;
IGameInputDevice* g_gamepad = nullptr;

HRESULT InitializeInput()
{
    return GameInputCreate(&g_gameInput);
}

void ShutdownInput()
{
    if (g_gamepad) g_gamepad->Release();
    if (g_gameInput) g_gameInput->Release();
}

void PollGamepadInput()
{
    // Ask for the latest reading from devices that provide fixed-format
    // gamepad state. If a device has been assigned to g_gamepad, filter
    // readings to just the ones coming from that device. Otherwise, if
    // g_gamepad is null, it will allow readings from any device.
    IGameInputReading * reading;
    if (SUCCEEDED(g_gameInput->GetCurrentReading(GameInputKindGamepad, g_gamepad, &reading)))
    {
        // If no device has been assigned to g_gamepad yet, set it
        // to the first device we receive input from. (This must be
        // the one the player is using because it's generating input.)
        if (!g_gamepad) reading->GetDevice(&g_gamepad);

        // Retrieve the fixed-format gamepad state from the reading.
        GameInputGamepadState state;
        reading->GetGamepadState(&state);
        reading->Release();

        // Application-specific code to process the gamepad state goes here.
    }

    // If an error is returned from GetCurrentReading(), it means the
    // gamepad we were reading from has disconnected. Reset the
    // device pointer, and go back to looking for an active gamepad.
    else if (g_gamepad)
    {
        g_gamepad->Release();
        g_gamepad = nullptr;
    }
}
```

<a id="seeAlsoSection" />

## 參考 API 文件

* [GameInput (API 內容)](/zh-TW/reference/input/gameinput/gameinput_members)

## 另請參閱

[GameInput 基本概念](/zh-TW/build/core-features/common/input/overviews/input-fundamentals)

[進階 GameInput 主題](/zh-TW/build/core-features/common/input/advanced/input-advanced-topics)

[GameInput API 參考](/zh-TW/reference/input/gc-reference-input-toc)


## Related topics

- [GameInput](/reference/input/gameinput/gameinput_members.md)
- [Overview of GameInput](/build/core-features/common/input/overviews/input-overview.md)
- [GameInput fundamentals](/build/core-features/common/input/overviews/input-fundamentals.md)
- [GameInput 概述](/zh-CN/build/core-features/common/input/overviews/input-overview.md)
- [GameInput 개요](/ko/build/core-features/common/input/overviews/input-overview.md)
