Twórz gry na wszystkie urządzenia

Podczas tworzenia gry na Androida ważne jest, by przewidywanie różnych opcji graczy i dostosowywanie się do potrzeb graczy związanych z interakcjami w czasie rzeczywistym. Odpowiadając za wrażenia różnych graczy, zwiększasz elastyczność gry i zwiększasz jej zasięg.

Szczególnie różnią się pod względem działania graczy:

  • Formaty urządzeń: chociaż telefony są typowe dla urządzeń z Androidem, możliwe jest granie na innych urządzeniach. Na urządzeniach z ChromeOS możesz uruchomić kontener Androida, który wyświetla Twoją grę. Tablety na Androidzie obsługują kilka różnych poziomów jakości. Urządzenia z Androidem TV obsługują więcej szczegółów i zapewniają bardziej atrakcyjne wrażenia. Za pomocą rozszerzenia do wyświetlania reklam odtwarzacze mogą symulować środowisko wielu okien. A jeśli używają urządzeń składanych, mogą zmieniać rozmiar ekranu podczas sesji rozgrywki.
  • Metody interakcji: gracze mogą wprowadzać dane, dotykając ekranu urządzenia, ale mogą też używać myszy, touchpada, klawiatury lub kontrolera. Ponadto dzięki dostępności narzędzi do rozszerzenia wyświetlacza i urządzeń składanych gracze mogą grać w grę na większym ekranie, co ułatwia dłuższe sesje gry i obsługuje bardziej złożone interfejsy.
  • Obsługa sprzętu: niektóre urządzenia z Androidem nie mają sprzętu, który jest bardziej typowy dla urządzeń mobilnych, np. tylnego aparatu, GPS-a czy łączności sieciowej. Gra powinna dostosowywać się do dostępnego sprzętu i grać płynnie działać w sytuacjach, gdy pewne funkcje są niedostępne.

W tym przewodniku przedstawiamy sprawdzone metody tworzenia gier pod kątem różnych rodzajów ekranów i interakcji użytkowników. Znajdziesz w nim również sugestie dotyczące zaprojektowania gry i opracowania skutecznej strategii testowania.

Sprawdzone metody projektowania gier

Podczas planowania projektu i architektury gry stosuj sprawdzone metody opisane w kolejnych sekcjach.

Ręczne reagowanie na zmiany konfiguracji

Gdy system Android wykryje zmianę konfiguracji, taką jak zmiana rozmiaru ekranu, orientacji ekranu czy metody wprowadzania, domyślnie ponownie uruchamia bieżącą aktywność. Aby zachować stan aplikacji lub gry, wykonywane są domyślne wywołania onSaveInstanceState() przed ponownym uruchomieniem i onRestoreInstanceState() po ponownym uruchomieniu. Ten proces wymaga jednak ponownego wczytania wszystkich powiązanych usług i zasobów. Więcej informacji o tym domyślnym zachowaniu znajdziesz w przewodniku dotyczącym obsługi zmian konfiguracji.

Zwykła sesja gry wymaga kilku zmian w konfiguracji. Jeśli gra pozwala systemowi na obsługę każdej zmiany konfiguracji, scena gry jest niszczona i wielokrotnie uruchamiana ponownie, co zmniejsza wydajność gry. Dlatego zdecydowanie zalecamy samodzielne wprowadzanie zmian konfiguracji w grze.

Aby dowiedzieć się, jak dodać do gry tę logikę zmian konfiguracji, zapoznaj się z sekcją tworzenia niestandardowych modułów obsługi zmian konfiguracji.

Tworzenie elastycznej architektury

Aby zapewnić obsługę gry na jak największej liczbie urządzeń, postępuj zgodnie z tymi sprawdzonymi metodami:

  • Wdrażaj pakiety Android App Bundle zamiast poszczególnych plików APK. Pakiety aplikacji na Androida umożliwiają grupowanie artefaktów o różnych rozdzielczościach i modelach architektury, np. x86 czy ARM, w jeden artefakt. Co więcej, pakiety Android App Bundle obsługują wyższe limity rozmiaru gry: każdy podstawowy plik APK może mieć do 150 MB, a pakiet może mieć wiele gigabajtów.
  • Dodaj obsługę architektur x86. Ten krok poprawia wydajność gry na urządzeniach, które nie obsługują ARM, ponieważ urządzenia te mogą teraz wykonywać instrukcje bez konieczności ich wcześniejszego tłumaczenia.

Dodaj obsługę interfejsu Vulkan

Dzięki obsłudze interfejsu Vulkan gra może poprawić wydajność grafiki. Większość urządzeń obsługuje ten interfejs API.

Tworzenie niestandardowych modułów obsługi zmian konfiguracji

Aby zadeklarować typy zmian w konfiguracji, które obsługuje gra, dodaj do każdego elementu <activity> w pliku manifestu atrybut android:configChanges, który reprezentuje złożony ekran lub złożony interfejs.

Ten fragment kodu pokazuje, jak zadeklarować, że gra uwzględnia rozmiar ekranu, orientację ekranu i zmiany metody wprowadzania:

<activity ...
    android:configChanges="screenSize|orientation|keyboard|keyboardHidden">
</activity>

Po wystąpieniu zadeklarowanych zmian w konfiguracji system wywołuje teraz inną metodę – onConfigurationChanged(). W ramach tej metody dodaj funkcje logiczne, aby zaktualizować interfejs gry:

Obsługuj zmiany w konfiguracji ekranu

Gra obsługuje ręcznie rozmiar i orientację ekranu, gdy umieścisz odpowiednio wartości screenSize i orientation w atrybucie android:configChanges. Możesz użyć tych nowych wartości, by zaktualizować treść sceny i obszary wejściowe odtwarzacza. Wskazówki dotyczące projektowania układu gry w taki sposób, aby ułatwić jego aktualizację, znajdziesz w przewodniku po obsłudze różnych rozmiarów ekranów.

W implementacji funkcji onConfigurationChanged() w grze użyj przekazanego obiektu Configuration oraz obiektu Display menedżera okien, aby określić zaktualizowane wartości rozmiaru i orientacji ekranu.

Ten fragment kodu pokazuje, jak uzyskać zaktualizowany rozmiar i orientację ekranu gry:

Kotlin

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    val density: Float = resources.displayMetrics.density
    val newScreenWidthPixels = (newConfig.screenWidthDp * density).toInt()
    val newScreenHeightPixels = (newConfig.screenHeightDp * density).toInt()

    // Get general orientation; either Configuration.ORIENTATION_PORTRAIT or
    // Configuration.ORIENTATION_LANDSCAPE.
    val newScreenOrientation: Int = newConfig.orientation

    // Get general rotation; one of: ROTATION_0, ROTATION_90, ROTATION_180,
    // or ROTATION_270.
    val newScreenRotation: Int = windowManager.defaultDisplay.rotation
}

Java

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    float density = getResources().getDisplayMetrics().density;
    int newScreenWidthPixels = (int) (newConfig.screenWidthDp * density);
    int newScreenHeightPixels = (int) (newConfig.screenHeightDp * density);

    // Get general orientation; either Configuration.ORIENTATION_PORTRAIT or
    // Configuration.ORIENTATION_LANDSCAPE.
    int newScreenOrientation = newConfig.orientation;

    // Get general rotation; one of: ROTATION_0, ROTATION_90, ROTATION_180,
    // or ROTATION_270.
    int newScreenRotation = getWindowManager().getDefaultDisplay()
            .getRotation();
}

Pamiętaj, że zmiana pozycji składanego urządzenia powoduje zmianę konfiguracji nawet wtedy, gdy aplikacja działa w trybie pełnoekranowym. W związku z tym aplikacja może reagować na zmiany rozmiaru ekranu lub gęstości pikseli, gdy użytkownik składa lub rozkłada urządzenie, gdy gra jest uruchomiona.

Jakość ekranu charakterystyczna dla gier

W tych sekcjach znajdziesz informacje o tym, jak w zależności od jakości gry dostosowywać sposób, w jaki gra reaguje na zmiany rozmiaru lub orientacji ekranu:

Tryb pełnoekranowy

Na niektórych platformach, np. w ChromeOS, aplikacje i gry na Androida mogą być domyślnie wyświetlane w oknach i z możliwością zmiany rozmiaru. Jeśli gra powinna zawsze działać w trybie pełnoekranowym, możesz ustawić wartość false atrybutu android:resizeableActivity w jednym z elementów <activity>, jak pokazano w tym fragmencie kodu:

<activity ...
    android:resizeableActivity="false">
</activity>

Możesz też ustawić wartość atrybutu android:resizeableActivity na false, aby zapobiec zmianie konfiguracji na podstawie rozmiaru. Jeśli jednak gra zawsze działa w trybie pełnoekranowym, należy dodać ten atrybut tylko jako tymczasową poprawkę na potrzeby testów.

Orientacja ekranu

Jeśli działanie gry zależy od czujników urządzenia w określonej orientacji, określ wartość android:screenOrientation w aktywności w grze, jak pokazano w tym fragmencie kodu. To ustawienie zapobiega nieoczekiwanemu odwróceniu sceny w grze.

<activity ...
    android:screenOrientation="landscape">
</activity>

Ustawienia ekranu na poszczególnych urządzeniach

W kolejnych sekcjach opisujemy, jak postępować ze zmianami konfiguracji na podstawie ekranu przy zastosowaniu określonych cech niektórych urządzeń.

Format obrazu

Niektóre urządzenia obsługują różne formaty obrazu. Na przykład urządzenia składane mogą obsługiwać proporcje obrazu 21:9 po złożeniu. Aby uwzględnić tę potencjalną różnorodność formatów obrazu, wykonaj co najmniej jedną z tych czynności:

  • Kieruj na Androida 8.0 (poziom API 26) lub nowszego.
  • Zmień rozmiar sceny i interfejsu w grze. Ustaw parametr android:resizeableActivity na true na urządzeniach z Androidem 7.0 (poziom interfejsu API 24) lub nowszym.
  • Zadeklaruj maksymalny obsługiwany współczynnik proporcji. W atrybucie <meta-data> powiązanym z Twoją grą ustaw android.max_aspect na 2.4, jak pokazano w tym fragmencie kodu. Pamiętaj jednak, że przy proporcjach większych niż określony przez Ciebie gra jest wyświetlana na ekranie z czarnymi pasami.

    <application>
    <meta-data android:name="android.max_aspect"
               android:value="2.4" />
    </application>
    

Widocznych jest wiele aktywności

Wiele nowoczesnych urządzeń obsługuje różne układy ekranu, w tym podzielony ekran, obraz w obrazie i duży obszar wyświetlania. Gdy używasz jednego z tych układów, system może wyświetlać jednocześnie wiele działań.

Na urządzeniach z Androidem 9 (poziom interfejsu API 28) lub nowszym możliwe jest wznowienie wszystkich widocznych działań w tym samym czasie. Aby jednak działało to poprawnie, zarówno gra, jak i producent urządzenia (producent) muszą włączyć tę funkcję. Aby dodać obsługę w swojej grze, ustaw wartość android.allow_multiple_resumed_activities na true w pliku manifestu gry, jak pokazano w tym fragmencie:

<application>
    <meta-data android:name="android.allow_multiple_resumed_activities"
               android:value="true" />
</application>

Możesz przetestować grę na różnych urządzeniach, aby sprawdzić, które z nich zapewniają obsługę OEM niezbędną do prawidłowego działania wielokrotnych wznowień.

Więcej informacji o konfigurowaniu gry jako części wyświetlacza z wieloma oknami znajdziesz w przewodniku po dodaniu obsługi trybu wielu okien.

Obsługa różnych typów modeli interakcji

Gra ręcznie obsługuje obecność klawiatury i dostępność klawiatury, gdy podasz odpowiednio wartości keyboard i keyboardHidden w atrybucie android:configChanges. Możesz użyć tych nowych wartości, aby zaktualizować podstawową metodę przesyłania w grze.

Konfigurując grę pod kątem obsługi wielu rodzajów danych wejściowych użytkownika, pamiętaj o tych kwestiach:

  • Wykrywaj metody wprowadzania, a nie poszczególne urządzenia. Takie podejście ułatwia poprawianie wrażeń graczy bez konieczności skupiania się zbytnio na konkretnym urządzeniu, którego używa.
  • Dodaj atrybut keyboardHidden na liście ręcznie obsługiwanych zmian konfiguracji. Dzięki temu gra może śledzić, czy klawiatura jest fizycznie podłączona do urządzenia, ale nie nadaje się do użycia.
  • Określ, które metody wprowadzania są obecnie dostępne. Aby to zrobić, wywołaj getInputDeviceIds() podczas uruchamiania gry i po każdej zmianie konfiguracji.

    Często można określić, jak gracz planuje interakcję z grą na podstawie preferowanego urządzenia wejściowego:

    • Gracze zwykle używają klawiatury lub kontrolera do gier, aby wykonywać szybkie sekwencje przycisków.
    • Aby wykonywać bardziej złożone gesty, gracze zwykle używają ekranu dotykowego lub touchpada.
    • Aby zwiększyć precyzję wprowadzania danych, gracze zwykle używają myszy.

W sekcjach poniżej znajdziesz sprawdzone metody dotyczące określonych typów urządzeń wejściowych.

Klawiatura

Podczas wybierania układu klawiatury w grze weź pod uwagę sposób, w jaki gracz porusza się po danej scenie, a także sposób interakcji z ustawieniami gry.

Do sterowania ruchami znaków zazwyczaj najlepiej nadają się klawisze WASD lub klawisze strzałek. Najlepiej jest przypisać klucz do każdego ważnego działania lub umiejętności, które postać, którą można sterować, może wykonać w grze. Aby zapewnić graczom jak najlepsze wrażenia, pomyśl o dodaniu w grze obsługi niestandardowych powiązań klawiszy.

Gracze powinni też mieć możliwość otwierania menu gry i poruszania się po nich za pomocą klawiatury. Klawisz Esc jest typowym mapowaniem do wstrzymywania sceny i wyświetlania menu gry.

Więcej informacji o obsłudze wprowadzania tekstu z klawiatury w grze znajdziesz w przewodniku po obsłudze nawigacji przy użyciu klawiatury oraz w poradniku na temat obsługi poleceń klawiatury.

Kontroler do gier

Więcej informacji o obsłudze danych wejściowych kontrolera w grze znajdziesz w przewodniku na temat obsługi kontrolerów do gier.

Mysz lub touchpad

Jeśli Twoja gra obsługuje wprowadzanie danych za pomocą myszy lub touchpada, pamiętaj, że gracze mogą sterować urządzeniem w inny sposób niż podczas grania. Pamiętaj, że gdy zażądasz przechwytywania wskaźnika, wszystkie dane wejściowe myszy są kierowane do Twojej gry. Dlatego gdy gra zbierze potrzebne informacje, zwolnij przechwytywanie wskaźnika, aby gracze mogli odzyskać standardową kontrolę nad urządzeniem za pomocą myszy.

Na urządzeniach z Androidem 8.0 (poziom interfejsu API 26) lub nowszym można użyć interfejsu MouseCapture API do przechwytywania wskaźników. W grach, które reagują na bardzo precyzyjne dane wejściowe, możesz uzyskać aktualne współrzędne wskaźnika, wywołując metody getX() i getY().

Dodatkowe informacje o dodaniu obsługi wprowadzania danych za pomocą myszy i touchpada w grze znajdziesz w poradniku śledzenia ruchu dotykowego i wskaźników oraz przewodniku na temat obsługi gestów dotykowych.

Testowanie gry

Zanim uruchomisz grę, sprawdź, jak reaguje na zmiany w konfiguracji, wykonując czynności opisane w sekcjach poniżej.

Aktualizowanie planu testów

Podczas weryfikowania funkcji gry uwzględnij te przypadki testowe:

  • Minimalizuj i maksymalizuj okno, które zawiera grę. Nie ma zastosowania, jeśli gra jest zawsze w trybie pełnoekranowym.
  • Zmień rozmiar ekranu.
  • Zmień orientację ekranu. Nie ma zastosowania, jeśli gra ma stałą orientację.
  • Umożliwia podłączanie i odłączanie urządzeń wejściowych, takich jak klawiatury czy myszy.
  • Wykonaj wielokrotne wznawianie, jeśli Twoja gra to umożliwia.

Zastanów się też nad zaktualizowaniem systemu kontroli jakości gry, aby zoptymalizować ją pod kątem bardziej zróżnicowanych graczy.

Sprawdzone metody testowania gry znajdziesz w przewodniku po podstawach testowania.

Korzystanie z narzędzi do testowania i debugowania

Testy można przeprowadzać za pomocą różnych narzędzi obsługiwanych przez platformę: