13. díl - Programujeme Android hru - Krmení II

Java Android Programujeme hru Programujeme Android hru - Krmení II

Zdravím vás v dalším díle našeho kurzu. V tom minulém jsme navenek nepřidali žádnou funkcionalitu, pouze jsme přidali dvě třídy. Dnes si ve stručnosti popíšeme jejich princip a rozjedeme promítání krmení na obrazovku.

Začneme proměnnými třídy PosFinder.java, screen konstanty dobře známe, beginConstant též známe a je okomentovaná. Random je jasná, slouží k vylosování souřadnic. Instance třídy PosFinder.java musí při každém hledání volného místa mj. znát:

  • aktuální polohu kuřete
  • rozměry kuřete
  • rozměry krmiva

První dvě položky ukládáme do proměnné receivedRectangle a do proměnných width, height rozměry krmiva.

Dvouprvkové float pole generatedPosition je konečným výstupem a obsahuje vylosované vhodné souřadnice, na které je možné krmení v daný okamžik umístit.

Pole area[] inicializujeme v konstruktoru kódem:

this.area = new Rectangle[4];
for (int i = 0; i < area.length; i++)
        area[i]=new Rectangle();

Tedy jako pole čtyř obdélníků, proč zrovna tak? Na to více než slova odpoví obrázky:

PodminkaAC

PodminkaAB

PodminkaE

Ano, plochu, po které může naše hloupá slepice chodit, jsme si rozdělili na 4 oblasti. Ať slepice půjde po našem "jevišti" kamkoli, vždy vzniknou 2, 3 nebo 4 oblasti (obdélníky), které jsou vhodné pro umístění krmení.

Jak to funguje?

Souřadnice krmiva mají nějakou dobu životnosti, která je dána odčítáním proměnné lifeTime instance třídy Food.java. Vždy, když je proměnná lifeTime <= 0, zavolá se metoda findOutFreePo­sition(...), která dle aktuální pozice kuřete stanoví, zda se utvořily 2, 3, nebo 4 zmíněné oblasti (obdélníky). Korekce pomocí proměnné coefficient zabezpečí, aby oblasti vznikly teprve tehdy, až pro ně bude existovat větší místo, než je velikost krmiva, tedy minimálně 32*1,25 px, abychom měli z čeho losovat.

Podle vzniklých oblastí metoda findOutFreePo­sition(...) zavolá s příslušným char argumentem metodu generatePositi­on(...), která dle tohoto argumentu vybere konkrétní oblasti a nastaví je na konkrétní rozměry, dle aktuální pozice kuřete. Posledním úkolem metody generatePositi­on(...) je zavolání metody setCoordinate(...), která vylosuje oblast a souřadnice, na kterých se má krmivo objevit a nastaví tyto souřadnice do pole generatedPosition. Řízení se vrátí metodě findOutFreePo­sition(...), která vrací pole s požadovanými souřadnicemi.

Třída Food.java

Instance bude mít nějaké rozměry, dále souřadnice, kde se na obrazovce nachází (WIDTH, HEIGHT, positionX, positionY). Proměnnou lifeTime jsem již objasnil výše. Ještě k ní dodám, že je inicializovaná pomocí newLifeTime, protože postupně chceme snižovat dobu životnosti krmiva a tím zvyšovat obtížnost hry. Do counter se postupně přičítá delta a až součet dosáhne určité hodnoty, vyvolá to snížení hodnoty newLifeTime. Proměnná rectForOverlap bude sloužit k detekci kolize krmiva a kuřete. Vždy při promítnutí krmiva na nových souřadnicích se zobrazí jiný obrázek, toto přepnutí zajistí proměnná mask.

Řádek s výčtovými konstantami enum Type {WHEAT,CORN,BERRY,CARROT} jsem odstranil (vykomentoval). Pravdivostní wasClicked a wasCounted slouží k tomu, aby vyhodnocení kliknutí na krmivo a započítání bodu bylo provedeno jen jednou.

Promítání krmení

Co musíme splnit pro promítnutí krmiva?

  • načíst potřebné obrázky krmení ve třídě Assets.java
  • vytvořit instanci dle třídy Food.java a volat metodu update(...) této instance
  • renderovat instanci

Do složky assets přidáme 4 soubory obrázků krmení, jsou součástí balíku ke stažení dole. Ve třídě AssetManager.java tyto obrázky načteme do paměti, výsledná podoba třídy:

public class AssetManager {
        public static Texture background;
        public static TextureRegion rBackground;
        public static Texture left1,left2,leftSideDown1,leftSideDown2,leftSideUp1,leftSideUp2;
        public static Texture right1,right2,rightSideDown1,rightSideDown2,rightSideUp1,rightSideUp2;
        public static Texture carrot,autumn,corn,wheat;

        public static Texture standLeft12;                      //na animaci oka
        public static TextureRegion rStandLeft1,rStandLeft2;    //na animaci oka
        public static Animation standLeftAnime;                 //na animaci oka

        public static Texture standRight12;                     //na animaci oka
        public static TextureRegion rStandRight1,rStandRight2;  //na animaci oka
        public static Animation standRightAnime;                //na animaci oka


        public static void load() {
                background = new Texture(Gdx.files.internal("background.png"));
                background.setFilter(TextureFilter.Nearest, TextureFilter.Nearest); //proti rozmazavani pri roztahovani

                rBackground = new TextureRegion(background,0,0,800,500);
                rBackground.flip(false, true);

                carrot = new Texture(Gdx.files.internal("carrot.png"));
                carrot.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
                autumn = new Texture(Gdx.files.internal("autumn.png"));
                autumn.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
                corn = new Texture(Gdx.files.internal("corn.png"));
                corn.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
                wheat = new Texture(Gdx.files.internal("wheat.png"));
                wheat.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                left1 = new Texture(Gdx.files.internal("left1.png"));
                left1.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                left2 = new Texture(Gdx.files.internal("left2.png"));
                left2.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                leftSideDown1 = new Texture(Gdx.files.internal("leftsidedown1.png"));
                leftSideDown1.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                leftSideDown2 = new Texture(Gdx.files.internal("leftsidedown2.png"));
                leftSideDown2.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                leftSideUp1 = new Texture(Gdx.files.internal("leftsideup1.png"));
                leftSideUp1.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                leftSideUp2 = new Texture(Gdx.files.internal("leftsideup2.png"));
                leftSideUp2.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                right1 = new Texture(Gdx.files.internal("right1.png"));
                right1.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                right2 = new Texture(Gdx.files.internal("right2.png"));
                right2.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                rightSideDown1 = new Texture(Gdx.files.internal("rightsidedown1.png"));
                rightSideDown1.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                rightSideDown2 = new Texture(Gdx.files.internal("rightsidedown2.png"));
                rightSideDown2.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                rightSideUp1 = new Texture(Gdx.files.internal("rightsideup1.png"));
                rightSideUp1.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

                rightSideUp2 = new Texture(Gdx.files.internal("rightsideup2.png"));
                rightSideUp2.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);


                /* zacatek obsluhy animace mrkani oka, kdyz kure stoji doleva nebo doprava */
                standLeft12 = new Texture(Gdx.files.internal("standleft12.png"));
                standLeft12.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
                rStandLeft1 = new TextureRegion(standLeft12,0,0,115,90);
                rStandLeft1.flip(false, false);
                rStandLeft2 = new TextureRegion(standLeft12,115,0,115,90);
                rStandLeft2.flip(false, false);
                TextureRegion[]rStandLeft12={rStandLeft1,rStandLeft1,rStandLeft1,
                rStandLeft1,rStandLeft1,rStandLeft2};
                standLeftAnime = new Animation(0.2f, rStandLeft12);
                standLeftAnime.setPlayMode(Animation.PlayMode.LOOP_PINGPONG);

                standRight12 = new Texture(Gdx.files.internal("standright12.png"));
                standRight12.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
                rStandRight1 = new TextureRegion(standRight12,0,0,115,90);
                rStandRight1.flip(false, false);
                rStandRight2 = new TextureRegion(standRight12,115,0,115,90);
                rStandRight2.flip(false, false);
                TextureRegion[]rStandRight12={rStandRight1,rStandRight1,rStandRight1,
                rStandRight1,rStandRight1,rStandRight2};
                standRightAnime =  new Animation(0.2f, rStandRight12);
                standRightAnime.setPlayMode(Animation.PlayMode.LOOP_PINGPONG);
                /* konec obsluhy animace mrkani oka, kdyz kure stoji doleva nebo doprava */

        }
}

Vytvoření instance dle třídy Food.java a volání metody update(...)

Do třídy ObjectManager.java přidáme tyto řádky:

private Food food;
this.food = new Food(gameScreen, chicken, BEGINYCONSTANT);
food.update(delta);

public Food getFood() {
        return food;
}

Přidáme importy a uložíme. Již nemáme prostor dělat výpis celé třídy, takže pokud si nejsme jisti, kam řádky do třídy přidat, podíváme se do zdrojového kódu, který je na konci této kapitoly ke stažení.

Promítnutí krmení

Do třídy Renderer.java přidáme následující kód:

private Food food;
private Texture carrot, autumn, corn, wheat;

this.carrot = AssetManager.carrot;
this.autumn = AssetManager.autumn;
this.corn = AssetManager.corn;
this.wheat = AssetManager.wheat;

this.food = gameMng.getObjectManager().getFood();

drawFood();

private void drawFood() {
        if (food.getMask() == 0)
                batcher.draw(autumn, food.getPositionX(),food.getPositionY(),food.getWidth(),food.getHeight());
        else if(food.getMask()==1)
                batcher.draw(corn, food.getPositionX(),food.getPositionY(),food.getWidth(),food.getHeight());
        else if(food.getMask()==2)
                batcher.draw(wheat, food.getPositionX(),food.getPositionY(),food.getWidth(),food.getHeight());
        else
                batcher.draw(carrot, food.getPositionX(),food.getPositionY(),food.getWidth(),food.getHeight());
}

Přidáme importy a uložíme. Stejně jako v předchozí třídě, pokud si nejsme jisti, kam řádky do třídy přidat, podíváme se do zdrojového kódu. Aplikaci spustíme a pokud máme vše správně, postupně se nám za sebou promítnou krmiva bobule, kukuřice, pšenice a mrkev na náhodných souřadnicích.


 

Stáhnout

Staženo 5x (6.1 MB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

  Aktivity (3)

Č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?
Ještě nikdo nehodnotil, buď první!


 


Miniatura
Všechny články v sekci
Programujeme Android hru

 

 

Komentáře

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.

Zatím nikdo nevložil komentář - buď první!