IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

13. diel - Programujeme Android hru - Kŕmenie II

Zdravím vás v ďalšom diele nášho kurzu. V tom minulom sme navonok nepridali žiadnu funkcionalitu, iba sme pridali dve triedy. Dnes si v stručnosti popíšeme ich princíp a rozbehneme premietanie kŕmenie na obrazovku.

Začneme premennými triedy PosFinder.java, screen konštanty dobre poznáme, beginConstant tiež poznáme a je okomentované. Random je jasná, slúži na vyžrebovanie súradníc. Inštancie triedy PosFinder.java musia pri každom hľadaní voľného miesta oi. Poznať:

  • aktuálnu polohu kurčaťa
  • rozmery kurčaťa
  • rozmery krmivá

Prvé dve položky ukladáme do premennej receivedRectangle a do premenných width, height rozmery krmiva.

Dvojprvkové float pole generatedPosition je konečným výstupom a obsahuje vyžrebované vhodné súradnice, na ktoré je možné kŕmenie v daný okamih umiestniť.

Pole area [] inicializujeme v konstruktoru kódom:

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

Teda ako pole štyroch obdĺžnikov, prečo práve tak? Na to viac než slová odpovie obrázky:

PodminkaAC - Programujeme Android hru
PodminkaAB - Programujeme Android hru
podmienkam - Programujeme Android hru

Áno, plochu, po ktorej môže naša hlúpa sliepka chodiť, sme si rozdelili na 4 oblasti. Nech sliepky pôjde po našom "javisku" kamkoľvek, vždy vzniknú 2, 3 alebo 4 oblasti (obdĺžniky), ktoré sú vhodné pre umiestnenie kŕmenie.

Ako to funguje?

Súradnice krmivá majú nejakú dobu životnosti, ktorá je daná odčítaním premenné Lifetime inštancie triedy Food.java. Vždy, keď je premenná Lifetime <= 0, zavolá sa metóda findOutFreePosition (...), ktorá podľa aktuálnej pozície kurčaťa určí, či sa utvorili 2, 3, alebo 4 spomínané oblasti (obdĺžniky). Korekcia pomocou premennej coefficient zabezpečí, aby oblasti vznikli až vtedy, až pre nich bude existovať väčšie miesto, než je veľkosť krmiva, teda minimálne 32 * 1,25 px, aby sme mali z čoho losovať.

Podľa vzniknutých oblastí metóda findOutFreePosition (...) zavolá s príslušným char argumentom metódu generatePosition (...), ktorá podľa tohto argumentu vyberie konkrétne oblasti a nastaví ich na konkrétne rozmery, podľa aktuálnej pozície kurčaťa. Poslednou úlohou metódy generatePosition (...) je zavolaní metódy setCoordinate (...), ktorá vyžrebuje oblasť a súradnice, na ktorých sa má krmivo objaviť a nastaví tieto súradnice do poľa generatedPosition. Riadenie sa vráti metóde findOutFreePosition (...), ktorá vracia pole s požadovanými súradnicami.

Trieda Food.java

Inštancie bude mať nejaké rozmery, ďalej súradnice, kde sa na obrazovke nachádza (WIDTH, HEIGHT, positionX, position). Premennú Lifetime som už objasnil vyššie. Ešte k nej dodám, že je inicializovaná pomocou newLifeTime, pretože postupne chceme znižovať dobu životnosti krmiva a tým zvyšovať obtiažnosť hry. Do counter sa postupne pripisuje delta a až súčet dosiahne určité hodnoty, vyvolá to zníženia hodnoty newLifeTime. Premenná rectForOverlap bude slúžiť na detekciu kolízie krmiva a kurčaťa. Vždy pri premietnutí krmiva na nových súradniciach sa zobrazí iný obrázok, toto prepnutie zaistí premenná mask.

Riadok s výčtovými konštantami enum Type {WHEAT,CORN,BERRY,CARROT} som odstránil (vykomentoval). Pravdivostná wasClicked a wasCounted slúži na to, aby vyhodnotenie kliknutie na krmivo a započítanie bodu bolo vykonané len raz.

Premietanie kŕmenie

Čo musíme splniť pre premietnutí krmivá?

  • načítať potrebné obrázky kŕmenie v triede Assets.java
  • vytvoriť inštanciu podľa triedy Food.java a volať metódu update (...) tejto inštancie
  • renderovať inštanciu

Do zložky assets pridáme 4 súbory obrázkov kŕmenia, sú súčasťou balíka na stiahnutie dole. V triede AssetManager.java tieto obrázky načítame do pamäte, výsledná podoba triedy:

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 */

    }
}

Vytvorenie inštancie podľa triedy Food.java a volanie metódy update (...)

Do triedy ObjectManager.java pridáme tieto riadky:

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

public Food getFood() {
    return food;
}

Pridáme importy a uložíme. Už nemáme priestor robiť výpis celej triedy, takže ak si nie sme istí, kam riadky do triedy pridať, pozrieme sa do zdrojového kódu, ktorý je na konci tejto kapitoly k stiahnutiu.

Premietnutí kŕmenie

Do triedy Renderer.java pridáme nasledujúci 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());
}

Pridáme importy a uložíme. Rovnako ako v predchádzajúcej triede, ak si nie sme istí, kam riadky do triedy pridať, pozrieme sa do zdrojového kódu. Aplikáciu spustíme a ak máme všetko správne, postupne sa nám za sebou premietnu krmivá bobule, kukurica, pšenica a mrkvu na náhodných súradniciach.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 28x (6.1 MB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Programujeme Android hru - Kŕmenie I
Všetky články v sekcii
Programujeme Android hru
Preskočiť článok
(neodporúčame)
Programujeme Android hru - Collision detection
Článok pre vás napísal Jaroslav Polívka
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje převážně jazykům JAVA a C++
Aktivity