> ## 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.

# IGameInput でネイティブ タッチ インターフェースを構築する

> IGameInput でゲーム用のネイティブ タッチ インターフェースを構築する

プレイヤーがモバイル デバイスにゲームをストリーミングする際、ゲームの楽しみを増やす最良の方法の 1 つは、タッチ操作でゲームと対話できるようにすることです。XBOX ゲーム ストリーミングは、[Touch Adaptation Kit](/build/core-features/common/game-streaming/game-streaming-touch-touch-adaptation-kit-overview) を使用してゲームにタッチ操作をオーバーレイする機能をサポートしており、これは、仮想ゲームパッドを持つことがゲームをプレイする自然な方法である多くのゲーム画面において素晴らしい選択となる場合があります。ただし、メニュー、マップ、インベントリ画面など、ゲームの一部部分では、タッチ入力で直接ゲームと対話する方が自然かもしれません。

たとえば、プレイヤーがメニュー オプションをタップして対話することはごく自然であり、モバイル フォンのジェスチャーを使用してマップをズームインしたり、スクロールしたりすることも同様です。Microsoft Game Development Kit (GDK) は、このネイティブ タッチ インターフェースをゲームに組み込むための API を提供し、それによって真のモバイル体験のように感じられるようにします。

Touch Adaptation Kit とネイティブ タッチは相互排他的ではなく、ゲームの中でタッチ入力が最も理にかなう場所で各形式のタッチ入力を使用しながら、両方をゲームで使用できます。たとえば、ネイティブ タッチのメニューを備えながらメイン ゲームプレイ ループには Touch Adaptation Kit を使用することは、タイトルのタッチ入力戦略を構築するための合理的な方法かもしれません。

<Note>ネイティブ タッチでゲームを構築している場合は、アカウント マネージャーにお知らせください。ゲームが小売環境にデプロイされたときにタッチ イベントを受け取れるようにするためには、XBOX Game Streaming のバックエンド サービスを構成する必要があります。</Note>

ネイティブ タッチは [IGameInputReading::GetTouchState](/reference/input/gameinput/deprecated/interfaces/igameinputreading/methods/igameinputreading_gettouchstate) API を介してゲームで利用できるようになります。この API は、プレイヤーが画面に触れている指の現在のセットを表す、現在のタッチ ポイントのセットを提供します。

これらのタッチ ポイントを押下、移動、リリースの各イベントに変換するには、各フレームでその状態を追跡することが有用な場合があります。

* 前のフレームには存在しなかったが、現在のフレームに存在するタッチ ポイントは、新しいタッチ プレスです
* 前のフレームに存在し、現在のフレームにもまだ存在するタッチ ポイントは、タッチの座標が変わっていなければ移動、変わっていなければ no-op です。
* 前のフレームに存在したが、もう存在しないタッチ ポイントはタッチ リリースです。

これらの押下、移動、リリースのイベントを構築するための非常に基本的な入力ループは、次のようになる場合があります。

```cpp theme={null}
struct TouchPoint
{
    // GameInputTouchState.touchId corresponding to this point
    uint64_t Id = 0;    

    // X pixel being touched
    uint32_t X = 0;

    // Y pixel being touched
    uint32_t Y = 0;

    // Is this entry in the array of touch points currently being used to track a touch
    bool IsInUse = false;

    // Is this TouchPoint tracking a finger which is currently touching the screen
    bool IsTouchActive = false;
};

// Touch points currently being tracked
std::array<TouchPoint, 10> g_touchPoints = {};

extern IGameInput* g_gameInput;
extern uint32_t g_frameWidth;
extern uint32_t g_frameHeight;

void TouchPointPressed(const TouchPoint& touchPoint);
void TouchPointMoved(const TouchPoint& touchPoint);
void TouchPointReleased(const TouchPoint& touchPoint);


void ProcessTouchInput()
{
    // Reset the active touch state from the previous frame
    for (TouchPoint& touchPoint : g_touchPoints)
    {
        touchPoint.IsTouchActive = false;
    }

    // Process any new touch points for this frame
    Microsoft::WRL::ComPtr<IGameInputReading> reading = nullptr;
    if (SUCCEEDED(g_gameInput->GetCurrentReading(GameInputKindTouch, nullptr, &reading)))
    {
        uint32_t touchCount = reading->GetTouchCount();
        if (touchCount > 0)
        {
            std::vector<GameInputTouchState> touchStates(touchCount);
            touchCount = reading->GetTouchState(touchCount, touchStates.data());

            for (const GameInputTouchState& touchState : touchStates)
            {
                const uint32_t x = static_cast<uint32_t>(touchState.positionX * g_frameWidth);
                const uint32_t y = static_cast<uint32_t>(touchState.positionY * g_frameHeight);

                // Check to see if we are already tracking this touch point
                auto existingPoint = std::find_if(std::begin(g_touchPoints), std::end(g_touchPoints), [id = touchState.touchId](const TouchPoint& point)
                {
                    return point.IsInUse && point.Id == id;
                });

                if (existingPoint != g_touchPoints.end())
                {
                    // We were already tracking the point - it is still alive this frame, but it may have
                    // also moved position.
                    existingPoint->IsTouchActive = true;
                    if (existingPoint->X != x || existingPoint->Y != y)
                    {
                        existingPoint->X = x;
                        existingPoint->Y = y;
                        TouchPointMoved(*existingPoint);
                    }
                }
                else
                {
                    // This is a new touch point. Start tracking it and treat it as a press
                    auto insertPoint = std::find_if(std::begin(g_touchPoints), std::end(g_touchPoints), [](const TouchPoint& point)
                    {
                        return !point.IsInUse;
                    });

                    if (insertPoint != std::end(g_touchPoints))
                    {
                        insertPoint->Id = touchState.touchId;
                        insertPoint->X = x;
                        insertPoint->Y = y;
                        insertPoint->IsInUse = true;
                        insertPoint->IsTouchActive = true;

                        TouchPointPressed(*insertPoint);
                    }
                }
            }
        }

        // Look for any points which were pressed last frame but are no longer pressed this frame
        // and treat those as touch releases
        for (TouchPoint& touchPoint : g_touchPoints)
        {
            if (touchPoint.IsInUse && !touchPoint.IsTouchActive)
            {
                TouchPointReleased(touchPoint);
                touchPoint = TouchPoint{};
            }
        }
    }
}
```


## Related topics

- [タッチ入門](/ja-jp/build/core-features/common/game-streaming/game-streaming-getting-started-with-touch.md)
- [タッチ コントロール構築のデザイナーズ ガイド](/ja-jp/build/core-features/common/game-streaming/building-touch-layouts/game-streaming-tak-designers-guide.md)
- [GameInput フォースフィードバックインターフェイス](/ja-jp/build/core-features/common/input/hardware/input-hardware-force-feedback.md)
- [GameInput](/ja-jp/reference/input/gameinput/gameinput_members.md)
- [さまざまな GameInput デバイス種別とのインターフェイス](/ja-jp/build/core-features/common/input/hardware/input-hardware-interfaces.md)
