Detecção de Toques com XNA 4.0

Com a vinda da versão 4.0 do XNA veio também o suporte do XNA ao Windows Phone 7, que será oficialmente lançado nesta segunda-feira(11/10/2010).
image
Uma das novas features mais interessantes é a capacidade de detectar facilmente pontos de toque na tela do dispositivo. A nova API de toques é muito simples de ser utilizada e, para qualquer pessoa que já utilizou as APIs de input do teclado, do mouse ou do gamepad, será um belo Déjà vu.
Para recuperar e utilizar os dados da API de toques, basta utilizar o método estático TouchPanel.GetState() que retorna um objeto do tipo TouchCollection. Este objeto é uma coleção de objetos do tipo TouchLocation. Cada TouchLocation corresponde a um ponto de toque na tela. Lembrando que os dispositivos com Windows Phone 7 devem suportar no mínimo 4 pontos de toque simultâneos.
Cada TouchLocation contêm 3 propriedades úteis: Id, Position e State. A propriedade Id é bem simples, um código de identificação, normalmente um número extenso. Este número é preservado enquanto o ponto existe. Position é um Vector2, com as coordenadas X e Y do centro do ponto de toque. State é uma variável do tipo enumerado TouchLocationState que pode ser:
  1. Invalid: Ponto inválido. O estado só esta Invalid quando você tenta recuperar um estado anterior de um ponto sendo que este ponto acabou de ocorrer.
  2. Moved: Este ponto foi atualizado, mudou de posição, ou pressionado no mesmo ponto.
  3. Pressed: Este ponto é novo, acabou de ocorrer.
  4. Released: Este ponto foi solto, liberado, ou seja, não esta mais sendo pressionado.
É válido lembrar que as APIs de toque do XNA 4 só funcionam para o Windows Phone 7. Não importa se você esta no Windows7, com uma tela multitoque. Se você executar o método TouchPanel.GetState() no Windows ou no XBox360, a API retorna um TouchCollection vazio, sempre! É um stub, ele não faz NADA, apenas retorna o TouchCollection vazio.
O último método interessante da API é o TouchLocation.TryGetPreviousLocation. Este método não é estático. Você o chama a partir de uma instância de TouchLocation passando um parâmetro de saida(out) do tipo TouchLocation. A função retorna neste parâmetro o ponto que ele era anteriormente. Como dito anteriormente, o ponto terá a propriedade State igual a Invalid quando o ponto que chamou a função for um ponto novo, ou seja, State igual a Pressed e o valor da propriedade Id será o mesmo do ponto anterior. O tipo de retorno da função é bool, retornando verdadeiro somente se o ponto que ele retorna no parâmetro de saida é válido.
Com esta configuração de estados e a função TryGetPreviousLocation você consegue descobrir quando um ponto foi criado e quando ele deixou de existir.
Como visto, a API é muito simples de se utilizar. Segue aqui um exemplo de código que testa todas as funcionalidade descritas.
C#
  1. protected override void Update(GameTime gameTime)
  2. {
  3. TouchCollection touchCollection = TouchPanel.GetState();
  4. if (touchCollection.Count > 0)
  5. {
  6. TouchLocation touchLocation1 = touchCollection.First();
  7. TouchLocation touchLocationAnterior;
  8. if (!touchLocation1.TryGetPreviousLocation(out touchLocationAnterior))
  9. {
  10. Debug.WriteLine(“Ponto anterior não existia!”);
  11. }
  12. if (touchLocation1.State == TouchLocationState.Moved && touchLocationAnterior.State == TouchLocationState.Pressed)
  13. {
  14. Debug.WriteLine(“Ponto novo criado(“ + touchLocation1.Position.ToString() + “). ID = “ + touchLocation1.Id.ToString());
  15. }
  16. if (touchLocation1.State == TouchLocationState.Released && touchLocationAnterior.State == TouchLocationState.Moved)
  17. {
  18. Debug.WriteLine(“Ponto não mais presente(“ + touchLocationAnterior.Position.ToString() + “). ID = “ + touchLocationAnterior.Id.ToString());
  19. }
  20. }
  21. base.Update(gameTime);
  22. }
Por hoje é só! Espero que este post tenha tirado as dúvidas de vocês em relação a esta nova API de toques. Em breve irei comentar sobre a API de gestos, que facilita a criação de interfaces naturais ao usuário, como por exemplo Tap, Hold, Flick, Pinch, entre outros.
Obrigado pelo seu tempo e até o próximo post,
Alexandre Z. Chohfi

2 Respostas

  1. Olá,
    Parabéns pelo post.
    Estou utilizando TouchCollection em um projeto que solta um som toda vez que ele acerta uma posição. O problema é que quando clico no ponto certo o som é executado varias vezes com microsegundos de diferença. Gostaria de que o som fosse executado apenas uma vez a cada toque.
    Abrs

    • Olá Rafael.

      Cada TouchLocation de uma TouchCollection tem uma propriedade chamada State, que é um tipo enumerado chamado TouchLocationState com as opções Invalid, Moved, Pressed ou Released. Se você quer que este ponto seja detectado apenas quando ele for pressionado pela primeira vez, verifique se a propriedade State do TouchLocation é igual a TouchLocationState.Pressed. Ela só ocorre no momento em que o dedo é colocado sobre a tela de toque. Todas as outras vezes, este ponto será considerado como TouchLocationState.Moved, mesmo quando o dedo não se moveu, indicando que é um ponto de toque que já existia antes.
      Creio que isso seja o suficiente para garantir que o som não toque mais de uma vez.

      Att,
      Alexandre Chohfi

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: