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

# Creación de una interfaz táctil nativa con IGameInput

> Creación de una interfaz táctil nativa para tu juego con IGameInput

Cuando los jugadores transmiten tu juego a sus dispositivos móviles, una de las mejores maneras de aumentar su disfrute del juego es permitirles interactuar con él mediante controles táctiles. XBOX game streaming permite superponer controles táctiles sobre tu juego mediante el [Touch Adaptation Kit](/build/core-features/common/game-streaming/game-streaming-touch-touch-adaptation-kit-overview), y esa puede ser una excelente opción para muchas pantallas de tu juego en las que tener un mando virtual es una forma natural de jugar. Sin embargo, para partes de tu juego como los menús, los mapas, las pantallas de inventario y otras, puede ser más natural interactuar con el juego directamente mediante entradas táctiles.

Por ejemplo, es muy natural que un jugador quiera tocar las opciones de un menú para interactuar con ellas, o que quiera usar gestos de teléfono móvil para hacer zoom en un mapa y desplazarse por él. Microsoft Game Development Kit (GDK) proporciona API que te permiten integrar esta interfaz táctil nativa en tu juego, haciendo que se sienta como una experiencia verdaderamente móvil.

El Touch Adaptation Kit y la entrada táctil nativa no son mutuamente excluyentes: puedes usar ambos en tu juego, empleando cada forma de entrada táctil donde tenga más sentido para tu título. Por ejemplo, tener menús con entrada táctil nativa mientras usas el Touch Adaptation Kit para el bucle de juego principal podría ser una forma razonable de estructurar la estrategia de entrada táctil de tu título.

<Note>Avisa a tu administrador de cuenta si estás creando un juego con entrada táctil nativa. Los servicios back-end de XBOX Game Streaming deberán configurarse para permitir que tu juego reciba eventos táctiles cuando el juego se implemente en entornos comerciales.</Note>

La entrada táctil nativa está disponible para tu juego a través de la API [IGameInputReading::GetTouchState](/reference/input/gameinput/deprecated/interfaces/igameinputreading/methods/igameinputreading_gettouchstate). Esta API te proporcionará el conjunto actual de puntos de contacto que representa el conjunto actual de dedos con los que el jugador está tocando la pantalla.

Para convertir estos puntos de contacto en eventos de pulsación, movimiento y liberación, puede resultar útil hacer un seguimiento de su estado en cada fotograma.

* Cualquier punto de contacto que no estuviera presente en el fotograma anterior pero que esté presente en el fotograma actual es una nueva pulsación táctil
* Cualquier punto de contacto presente en el fotograma anterior y que sigue presente en el fotograma actual es un movimiento o una operación sin efecto si las coordenadas del contacto no han cambiado.
* Los puntos de contacto que estaban presentes en el fotograma anterior pero que ya no están presentes son una liberación táctil.

Un bucle de entrada muy básico para generar estos eventos de pulsación, movimiento y liberación podría tener este aspecto:

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

- [Introducción a la entrada táctil](/es/build/core-features/common/game-streaming/game-streaming-getting-started-with-touch.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)
- [Compatibilidad táctil y de streaming de XBOX Cloud Gaming](/es/build/core-features/common/game-streaming/index.md)
- [IGameInput::FindDeviceFromObject](/es/reference/input/gameinput/deprecated/interfaces/igameinput/methods/igameinput_finddevicefromobject.md)
- [IGameInput::GetPreviousReading](/es/reference/input/gameinput/interfaces/igameinput/methods/igameinput_getpreviousreading.md)
