6. díl - Programujeme Android hru - Úvaha nad obrazovkami

Java Android Programujeme hru Programujeme Android hru - Úvaha nad obrazovkami

Při tvorbě jakékoli appky pro Android narazíme na problém s přizpůsobením pro mnoho displejů. Musíme se vypořádat s tím, že naše hra bude běžet na zařízeních s rozdílným rozlišením a poměrem obrazovky. Uvažujme tři konkrétní příklady tabletů:

  • Prestigio Multipad PMP 5780D s rozlišením 1024 x 768 pixelů tj. poměr 4:3
  • Samsung Galaxy Tab SM-T535NYKAXEZ s obrazovkou 1280 x 800 px tj. poměr 16:10
  • Alcatel One Touch Pop7 P310X s 1024 x 600 tj. téměř poměr 16:9

Problém nám v libgdx pomáhá řešit třída OrthographicCamera, díky které si v její instanci můžeme nastavil virtuální rozlišení, v této souvislosti mě napadají tři možnosti, jak orthocameru nastavit:

1. Nic neřešit a prostě orthokameře poručit svoje rozlišení. V tomhle vidím velký nedostatek, pokud například na obrazovce se skutečným poměrem obrazovky 16:9 nastavím rozlišení s poměrem 4:3, tak se obrázek neúměrně roztáhne, pokud to udělám opačně, tak se neúměrně smrskne a také se deformuje.

Kružnice se zobrazí jako elipsa

2. Ve virtuálním rozlišení využít prostě pouze poměr 4:3, protože předpokládám, že valná většina displejů je právě minimálně v poměru 4:3 (Všechny? Patří sem přece i množina 16:9.). No a zbývající pixely, které zůstanou navíc nad tento poměr, prostě nechat prázdné, či do nich umístit reklamu. Nazval bych to "preferovat obrazovky s poměrem 4:3". Jako výhodu tohoto postupu vidím jednoduchost, jako nevýhodu vidím to, že naše appka nechá na displejích s poměrem obrazovky větším než 4:3 nevyužité místo.

Obrazovku 4:3 zobrazíme na obrazovce 16:9

3. Další možnost bych nazval "preferovat širokoúhlé obrazovky" a spočívala by v tom, že obrázek v poměru např. 16:9 bych na obrazovce např. 4:3 zobrazil tak, že ho celý výrazně zmenším, ale stále bude v poměru 16:9, avšak dosti zmenšený na to, aby se vešel na obrazovku 4:3. Nevýhodu tohoto postupu vidím v tom, že uživatelé s displeji např. 4:3 uvidí obrázek dosti zmenšený (přijdou o mnoho detailů) a také v tom, že bude zbývat nějaké nevyužité místo. Naopak velkou výhodu spatřuji v tom, že budou využity "širokoúhlé" obrazovky v plné své síle a to bude také cesta, kterou se vydám, přičemž co je "širokoúhlé" a co už není, jsem si stanovil sám a to tak, že obrazovku, která má poměr 1,6 a více považuji za "širokoúhlou" a obrázky na ní nezmenšuji a na obrazovce, která je pod touto hodnotou obrázky zmenšuji. Tuto hodnotu jsem zvolil záměrně, protože výrobci tabletů, se kolem tohoto čísla točí opravdu často a také protože osobně považuji obrazovky s poměrovou hodnotou pod 1,6 za jakýsi "podstandard". Takže obrazovky 16:9 nebudou o detaily ochuzeny. Obrazovky 16:10 budou plně využity a to co je více a více pod 16:10 bude více a více ochuzeno, avšak stále funkční.

Na obrazovce 4:3 zobrazíme 16:9

Už jsem toho zase napsal dost, je čas jít něco nakódovat. Otevřeme si třídu GameScreen.java z minulého dílu a odstraníme v ní všechny proměnné, všechno z konstruktoru a vše také vyprázdníme z metody render (float delta). Přidáme importy (klávesová zkratka, aby nám naopak zmizely), takže to máme nějak takhle:

package com.wackychicken.screens;

import com.badlogic.gdx.Screen;

public class GameScreen implements Screen{

        public GameScreen(){

        }

        @Override
        public void show() {
        // TODO Auto-generated method stub

        }

        @Override
        public void render(float delta) {

        }

        @Override
        public void resize(int width, int height) {
                // TODO Auto-generated method stub

        }

        @Override
        public void pause() {
                // TODO Auto-generated method stub

        }

        @Override
        public void resume() {
                // TODO Auto-generated method stub

        }

        @Override
        public void hide() {
                // TODO Auto-generated method stub

        }

        @Override
        public void dispose() {
                // TODO Auto-generated method stub

        }

}

Do třídy si přidáme kód pro obsluhu nastavení obrazovky a celá třída GameScreen.java tak bude vypadat následovně:

package com.wackychicken.screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.math.Vector2;

public class GameScreen implements Screen{

private final float SCREENRATIO = 1.6f;
private float orthoWidth,orthoHeight;
private final Vector2 DEMANDED_SCREEN,SCREEN_BOUND_BEGIN,SCREEN_BOUND_END;

public GameScreen(){

                DEMANDED_SCREEN=new Vector2(800,500);

                float w = Gdx.graphics.getWidth();
                float h = Gdx.graphics.getHeight();

                if(w/h>=SCREENRATIO)//je to sirokouhly?
                {
                orthoWidth = w * (DEMANDED_SCREEN.y / h);
                orthoHeight = DEMANDED_SCREEN.y;
                SCREEN_BOUND_BEGIN=new Vector2( (orthoWidth - DEMANDED_SCREEN.x)/2, 0);
                SCREEN_BOUND_END=new Vector2(SCREEN_BOUND_BEGIN.cpy().add(DEMANDED_SCREEN));
                }

                else
                {
                orthoHeight = h * (DEMANDED_SCREEN.x / w);
                orthoWidth = DEMANDED_SCREEN.x;
                SCREEN_BOUND_BEGIN=new Vector2(0, (orthoHeight - DEMANDED_SCREEN.y) / 2);
                SCREEN_BOUND_END=new Vector2(SCREEN_BOUND_BEGIN.cpy().add(DEMANDED_SCREEN));
                }
}

        @Override
        public void show() {
        // TODO Auto-generated method stub

        }

        @Override
        public void render(float delta) {

        }

        @Override
        public void resize(int width, int height) {
                // TODO Auto-generated method stub

        }

        @Override
        public void pause() {
                // TODO Auto-generated method stub

        }

        @Override
        public void resume() {
                // TODO Auto-generated method stub

        }

        @Override
        public void hide() {
                // TODO Auto-generated method stub

        }

        @Override
        public void dispose() {
                // TODO Auto-generated method stub

        }

}

Uložíme, přidáme importy a zkusíme si spustit, zda nám Eclipse nevyhodí chybu. Zatím nebude v okně nic vidět, zatím nic nevykreslujeme. Virtuální rozlišení máme tímto ošetřené a jdeme trošku plánovat naší hru více do tříd. Podle naší dohody vytvořte:

  1. nový balík com.wackychic­ken.gameobjec­ts a v něm třídu Chicken.java
  2. nový balík com.wackychic­ken.managers a v něm třídy AssetManager.java, GameManager.java, InputManager.java, ObjectManager.java
  3. nový balík com.wackychic­ken.rendering a v něm třídu Renderer.java

tady je obrázek pro orientaci:

Balíčky a v nich třídy…

Třídy zatím ponecháme prázdné, psát do nich budeme od dalšího dílu, dnes si ještě řekneme, co budou mít jednotlivé třídy na starost, i když už je to patrné z jejich názvů.

  • Chicken.java - vytvoří instanci našeho hloupého kuřete
  • AssetManager.java - stará se o naloadování zdrojů do paměti (obrázky, zvuky)
  • GameManager.java - stará se o enum stav hry (ready,running,game over), počítá skóre
  • InputManager.java - obsluhuje události uživatelského vstupu, v našem případě to bude klik myší nebo dotyk prstem
  • ObjectManager.java - obsluhuje všechny pohyblivé objekty ve hře (slepici a žrádlo)
  • Renderer.java - promítačka, vykreslovač na virtuální obrazovku

Téměř všechny instance těchto tříd nám rozhýbe již předtím vytvořená třída GameScreen.java. To by bylo pro dnešek vše, příště navážeme. Celý zdrojový kód je samozřejmě přiložen.


 

Stáhnout

Staženo 2x (631.92 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

  Aktivity (4)

Článek pro vás napsal Jaroslav Polívka
Avatar
Autor se věnuje převážně jazykům JAVA a C++

Jak se ti líbí článek?
Celkem (1 hlasů) :
55555


 



 

 

Komentáře

Avatar
Michal Raška:

Osobně bych preferoval 2 varianty grafiky.

Pokud už bych se měl rozhodnout, tak spíše pro preferenci 4:3. V tomto případě dojde pouze k nevyužití místa u širokoúhlých displayů, ale nejmenší strana displaye je plně využita v obou variantách. Tím nedojde ke smrsknutí ovládání a zhoršení ergonomie.

Jak píšeš, je to sice funkční, ale nemusí to být už ovladatelné.

 
Odpovědět 2. července 17:18
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 1 zpráv z 1.