MonoGame – Gry na Androidzie!

W MonoGame możemy pisać nie tylko gry desktopowe, lecz także gry na platformy mobilne. Co najlepsze, niemal cały kod dowolnej gry napisanej w tym frameworku, możemy po prostu skopiować do nowego projektu przeznaczonego np. dla Androida i skompilować. Ten zabieg powinien wystarczyć, aby móc uruchomić naszą grę na telefonie/tablecie. Oczywiście są rzeczy, na które należy zwrócić szczególną uwagę… O czym przekonałem się na własnej skórze 😉

Czym się dzisiaj zajmiemy?

Na początku chciałem pokazać jak przenieść naszego Snake’a na telefon… Seria jest już jednak zamknięta, więc nie ma do czego wracać. Z drugiej strony myślę, że warto byłoby opisać tutaj kilka rzeczy, na które trzeba zwrócić uwagę pisząc grę dedykowaną na platformy mobilne. Ściślej mówiąc, zajmiemy się tutaj tylko Androidem 😉

Przeklęte emulatory…

Pierwszą rzeczą, z jaką trzeba się zmierzyć to wybór emulatora. Domyślnie z Visual Studio, po instalacji MonoGame, wraz z Android SDK będzie można uruchomić naszą aplikację z emulatorem dołączonym właśnie do tego SDK. Moje wrażenia? Strasznie to muli… Debugowanie nie działa. Efektywne testowanie zmian w projekcie jest po prostu nie możliwe. No, bo ile można czekać na uruchomienie aplikacji? Moje doświadczenia mówią o okresie około minuty, czasami dłużej… To skusiło mnie do poszukania czegoś lepszego. Natrafiłem na Xamarin Android Player. Jest on już nieco przyjemniejszy, działa lepiej – na pewno szybciej, z tym że do demona szybkości wiele temu brakuje. Jednak jeżeli chodzi o debugowanie… raz działa, raz nie… Może te problemy dotyczą tylko mnie –  szczerze powiedziawszy nie miałem już siły na szukanie innych emulatorów i rozwiązywania problemów z nimi, skoro mam… Normalny telefon z Androidem pod ręką 😉

Używaj emulatora, tylko wtedy kiedy nie możesz testować swojej aplikacji na dedykowanym dla niej systemie.

Taka tam moja mądrość 😉 No, bo po co się męczyć, skoro po podpięciu telefonu do komputera i włączeniu trybu debugowania Visual Studio automatycznie wykryje nasz telefon i umożliwi testowanie na nim naszej aplikacji? Co innego jeżeli nie posiadamy takiego urządzenia, wtedy jesteśmy zdani na emulatory…

Przygotowujemy nasze urządzenie do debugowania aplikacji

Całość operacji sprowadza się do podłączenia telefonu do portu USB w komputerze i uruchomienia debugowania USB, w telefonie. Najlepiej zrobić to z włączonym nowym projektem typu „MonoGame Android Project”.  W tym celu przechodzimy do ustawień naszego urządzenia i wybieramy pozycję „Opcje programistyczne” -> „Debugowanie USB”. Po zaznaczeniu tego CheckBoxa, powinno nas powitać okienko jak poniżej. Oczywiście zezwalamy na debugowanie.

screenshot_2016-09-24-15-47-32 screenshot_2016-09-24-15-47-57

 

 

 

 

 

 

 

 

Po wykonaniu tych czynności w Visual Studio, powinniśmy już mieć możliwość uruchomienia naszego (póki co) pustego projektu:

psp

W moim przypadku jest to urządzenie Prestigio z Androidem 4.4.2 na pokładzie. Nie mam niestety pojęcia od jakiej dokładnie wersji Androida gry pisane w MonoGame działają. Z moich testów wynika, że na wersji 4.1.x moja gra się uruchomiła, na wersji 2.x.x(konkretnej liczby nie pamiętam) już nie. Udało mi się jednak wygooglać, że teoretycznie MonoGame wspiera Androida, od wersji 2.3 (API level 9) – skoro tak piszą, to widocznie tak jest 😉

Dobrze, skoro wszystko gotowe to kliknijmy na ten magiczny zielony przycisk Play i sprawdźmy czy nasz projekt się faktycznie na naszym urządzeniu uruchomi.

UWAGA: Jeżeli pojawią się jakiekolwiek problemy, warto przenieść projekt do folderu, którego ścieżka nie zawiera polskich znaków. Ich obecność może powodować błędy w kompilacji, bądź uruchomieniu debugowania projektu.

Jeżeli wszystko poszło dobrze, na telefonie automatycznie powinna się uruchomić pusta gra:

screenshot_2016-09-24-16-23-18

Natomiast Visual Studio powinien trudzić się zgarnianiem logów z działania naszej aplikacji 😉

logs

Jeżeli w aplikacji wystąpi jakiś wyjątek… Zostaniemy tutaj o tym poinformowani. No, cóż… Jeżeli chodzi o testowanie naszej aplikacji to wszystko gotowe. Teraz można wziąć się za nic innego jak pisanie. Zróbmy, więc coś prostego. Na przykład apkę, która będzie wyświetlała pozycję XY, miejsca którego właśnie dotykamy. Wszakże obsługa dotyku to podstawa przy programowaniu gier dla tabletów/telefonów. Mile widziana jest też implementacja obsługi myszki/klawiatury – jednak szczerze mówiąc… raczej niewiele osób z nich korzysta na urządzaniach z Androidem. Do dzieła, więc!

Obsługa dotyku

Pierwszą rzeczą jaką się zajmiemy, będzie wyświetlanie wartości X i Y na ekranie. W tym celu stwórzmy sobie nowego font’a w zasobach naszego projektu:

ss

Po jego dodaniu wczytamy go, w metodzie LoadContent():

Następnie w metodzie Draw(), wyświetlmy wartości na których będziemy za chwilę operować:

W tym momencie możemy już wyświetlić dowolnego string’a, to właśnie mu będziemy przypisywać wartości X i Y, dotykanego przez nas na ekranie miejsca. Przypiszmy zmiennej XYString jakąś początkową wartość – nie możemy wyświetlać null’a 😉

Zajmijmy się teraz obsługą panelu dotykowego. Pierwszą rzeczą, jaką musimy zrobić to dodać nową zmienną typu TouchCollection do projektu. Znajduje się ona w przestrzeni nazw Microsoft.Xna.Framework.Input.Touch;

Teraz możemy z powodzeniem stworzyć nową metodę, służącą do obsługi dotyku:

Co tu się dzieje? Pierwsza linijka pobiera dane nt. statusu panelu dotykowego m.in również pozycję dotykanego miejsca. Następnie „wyjmujemy” z elementu touchCollection lokalizację dotykanego miejsca i ją wyświetlamy. Proste prawda? Możemy pokusić się o rozbudowanie tej metody o kilka kolejnych podstawowych funkcji, które udostępnia nam MonoGame 😉

Wszystko jest chyba wystarczająco wytłumaczone w komentarzach. Jeżeli chodzi o dotyk, wydaje mi się że tyle z podstaw wystarczy, żeby stworzyć jakąś prostą gierkę na telefony/tablety. Należy oczywiście pamiętać o wywołaniu tej metody w metodzie Update():

Efekt końcowy:

screenshot_2016-09-24-17-32-511

Na co jeszcze trzeba zwracać uwagę?

Jeżeli przenosisz grę napisaną na komputer, to strzeż się kodu odpowiedzialnego za operacje typu: włącz/wyłącz możliwość rozszerzania okna, włącz/wyłącz widoczność kursora, oraz wszelkich innych operacji, które pośrednio bądź bezpośrednio manipulują rzeczami, które dostępne są tylko na systemie, na którym pisałeś grę. Zamykanie gry, nie może odbywać się za pomocą metody Exit();, udostępnianej przez MonoGame. To znaczy… może się tak odbywać. Tylko problem w tym, że gra nie zostanie zamknięta, tylko „zawieszona”. Gra faktycznie zostanie zamknięta, dopiero po wywołaniu metody: Activity.Finish();. Czyli metody de facto z Android API. Należy także unikać, używania czegokolwiek co nie jest dostępne na Androidzie. Na przykład okien WPF… Czy innych bibliotek nie przystosowanych do działania na tym systemie… chociaż to jest oczywiste 😉