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

# Criar uma interface de toque nativa com IGameInput

> Como criar uma interface de toque nativa para seu jogo com IGameInput

Quando os jogadores fazem streaming do seu jogo para os dispositivos móveis deles, uma das melhores formas de aumentar a diversão é permitir que eles interajam com o jogo usando controles de toque.  O XBOX Game Streaming permite sobrepor controles de toque ao seu jogo usando o [Touch Adaptation Kit](/pt-BR/build/core-features/common/game-streaming/game-streaming-touch-touch-adaptation-kit-overview), e essa pode ser uma ótima opção para muitas telas do seu jogo em que ter um gamepad virtual é uma forma natural de jogar. No entanto, para partes do jogo como menus, mapas, telas de inventário e outras, pode ser mais natural interagir com o jogo diretamente por meio de entradas de toque.

Por exemplo, é muito natural que um jogador queira tocar nas opções de menu para interagir com elas ou usar gestos de celular para ampliar e rolar um mapa.  O Microsoft Game Development Kit (GDK) fornece APIs que permitem criar essa interface de toque nativa no seu jogo, fazendo com que ele pareça uma experiência verdadeiramente móvel.

O Touch Adaptation Kit e o toque nativo não são mutuamente exclusivos: você pode usar os dois no seu jogo, aplicando cada forma de entrada por toque onde fizer mais sentido para o seu título. Por exemplo, ter menus com toque nativo enquanto usa o Touch Adaptation Kit para o loop de jogabilidade principal pode ser uma forma razoável de estruturar a estratégia de entrada por toque do seu título.

<Note>Notifique seu gerente de conta se você estiver criando um jogo com toque nativo.  Os serviços de back-end do XBOX Game Streaming precisarão ser configurados para permitir que seu jogo receba eventos de toque quando ele for implantado em ambientes de varejo.</Note>

O toque nativo é disponibilizado ao seu jogo por meio da API [IGameInputReading::GetTouchState](/pt-BR/reference/input/gameinput/deprecated/interfaces/igameinputreading/methods/igameinputreading_gettouchstate). Essa API fornece o conjunto atual de pontos de toque que representam os dedos com os quais o jogador está tocando a tela no momento.

Para converter esses pontos de toque em eventos de pressionamento, movimento e liberação, pode ser útil acompanhar o estado deles em cada quadro.

* Qualquer ponto de toque que não estava presente no quadro anterior, mas está presente no quadro atual, é um novo pressionamento de toque
* Qualquer ponto de toque presente no quadro anterior e ainda presente no quadro atual é um movimento ou uma operação nula, caso as coordenadas do toque não tenham mudado.
* Pontos de toque que estavam presentes no quadro anterior, mas não estão mais presentes, são uma liberação de toque.

Um loop de entrada bem básico para criar esses eventos de pressionamento, movimento e liberação pode ter a seguinte aparência:

```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

- [Creación de una interfaz táctil nativa con IGameInput](/es/build/core-features/common/game-streaming/game-streaming-native-touch-igameinput.md)
- [Guía del diseñador para crear controles táctiles](/es/build/core-features/common/game-streaming/building-touch-layouts/game-streaming-tak-designers-guide.md)
- [Tags de recursos de acessibilidade](/pt-BR/build/game-principles/accessibility/accessibility-feature-tags.md)
- [IGameInputReading::GetMouseState](/es/reference/input/gameinput/interfaces/igameinputreading/methods/igameinputreading_getmousestate.md)
- [IGameInput::UnregisterCallback](/es/reference/input/gameinput/interfaces/igameinput/methods/igameinput_unregistercallback.md)
