WP XNA 8: Większa kontrola nad gestami (Raw gestures)

Windows Phone 7 GesturesZapewne każdy zna podstawowe gesty ekranów dotykowych. Wiemy też, że każdy telefon z Windows Phone 7 musi spełniać kilka podstawowych wymagań w tej dziedzinie (np. obsługa co najmniej 4 punktów dotyku). Co więcej, w SDK (dokładnie w XNA Framework) znajdziemy wbudowana obsługę pewnych gestów (np. Tap, FreeDrag, DoubleTap, Vertical/HorizontalDrag, Pinch itd). Ale jeśli to dla nas za mało to zakłwsze możemy „zejść” na niższy poziom API i tworzyć własne gesty.

Ten wpis jest częścią cyklu o moich przygodach w tworzeniu gier XNA dla Windows Phone.

Podstawowa obsługa gestów

Dodanie obsługi podstawowych gestów jest bardzo proste i nie wymaga to wiele pracy z naszej strony. Najpierw informujemy statyczną klasę TouchPanel jakie gesty nas interesują:

TouchPanel.EnabledGestures = GestureType.Tap | GestureType.Pinch | GestureType.PinchComplete;

GestureType jest enum’em gdzie znajdują sie wszystkie wbudowane w system gesty.

Następnie w metodzie Update sprawdzamy czy są dla nas jakieś gesty, a jeśli tak to jakiego typu i wówczas wykonujemy odpowiednie operacje:

while (TouchPanel.IsGestureAvailable)
{
	var gesture = TouchPanel.ReadGesture();
	if (gesture.GestureType == GestureType.Tap)
	{
		// tapnięcie
		// przesuń grasza
		player.Position = gesture.Position;
	}
	else if (gesture.GestureType == GestureType.Pinch)
	{
		// pinch-zoom
		// ...
	}
}

Zaawansowana obsługa gestów

Niestety czasami to co dostajemy za darmo (wbudowane gesty) to za mało. Poniżej dwa przykłady dlaczego i kiedy:

  • Obsługa wielu gestów naraz. Trzeba zdać sobie sprawę, że multi-touch, to nie to samo co multile-multi-touch. Pinch jest gestem typu multi-touch (bo wymaga 2 palców), a co z równoczesnym Tap, albo DoubleTap? Takiego wsparcia nie ma w SDK i trzeba sięgać niżej…
  • Boss HunterPrzykład z mojej aplikacji. Użytkownik za pomocą palca kieruje małym samolotem na ekranie. Ruch samolotu jest powolny, czyli samolot „leci” za palcem gracza ze swoja prędkością. Wydawało by się, że Tap oraz FreeDrag idealnie się do tego nadaja. Niestety okazało się, że gdy palec się zatrzymał, samolot już nie leciał dalej. Dlaczego? Gest FreeDrag jest zgłaczany tylko wówczas gdy trwa przesuwanie palca, a gdy przesuwany palec zatrzymamy, ale nadal go trzymamy na ekranie, gest FreeDrag nie jest zgłaszany (żaden gest się nie zgłasza). Raw gestures rozwiązało mój problem.

RawGestures

To czysta informacja, która pochodzi z klasy TouchPanel, która nie jest przetwarzana przez nic, tylko my sami musimy te informacje przetworzyć, zinterpretować i wykonać odpowiednie działania.

Do rozwiązania mojego problemu idealnie nadała się metoda GetState() klasy TouchPanel.

foreach (TouchLocation location in TouchPanel.GetState())
{
	int touchPointId = location.Id;
	Vector2 touchPoint = location.Position;

	// Twoja interpretacja
	// ...
}

Dla mnie istotne były dwie rzeczy

  • Nieważne co się działo z palcem – TouchPanel.GetState() zawsze zgłaszało, że „coś dla mnie ma”
  • Odczytany gest (typu TouchLocation) ma właściwość Position, czyli dla mnie była to aktualna pozycja  palca

Porada

Przy wejściu na stronę z grą (uruchomienie albo powrót do aplikacji) warto jest wyczyścić serię gestów, które mogły się przypadkowo pojawić. Dlaczego? Bywa tak, że gdy użytkownik wraca do gry to chcemy mu wyświetlić ekran z pauzą i czekamy na tapnięcie… a tu wpada „niekontrolowany” gest tapnięcia, który łapie pauza i użytkownik nawet nie zdąży jej zauważyć.

Można przykładowo utworzyć metodę ignorującą gesty w klasy TouchPanel:

private static void IgnoreAllCurrentGestures()
{
	while (TouchPanel.IsGestureAvailable)
		TouchPanel.ReadGesture();
}

Taką metodę możemy umieścić w OnNavigatedTo strony z grą:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
	SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true);

	// Load your content here

	timer.Start();

	base.OnNavigatedTo(e);
	IgnoreAllCurrentGestures();
}

Zachęcam do komentowania. Wszelkie uwagi, pytania, wasze rozwiązania czy znalezione u mnie błędy bardzo mile widziane.

Advertisements

2 thoughts on “WP XNA 8: Większa kontrola nad gestami (Raw gestures)

  1. Pingback: dotnetomaniak.pl

  2. Pingback: WP XNA 0: Wstęp | Wojciech Poniatowski [PL]

Możliwość komentowania jest wyłączona.