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

16. diel - Programujeme Android hru - Energia kurčaťa

Zdravím vás v ďalšom pokračovaní nášho kurzu, možno povedať, že dnešný diel bude takým podkladom pre nasledujúce diel, v ktorom pomocou switch rozvětvíme vykonávania kódu do rôznych stavov hry. Napríklad sliepky zdochne = dôjde jej energie, hra prejde do stavu GameOver. Algoritmus obsluhy energia bude vlastne postupným zvyšovaním obtiažnosti hry, pretože čím bude sliepky "starší", tým bude potrebovať viac a viac krmiva, aby jej energia rástla, nakoniec bude odčítanie premenné tak veľké, že už nebude možné sliepku uživiť a dôjde k jej úhynu - koniec hry. Vieme, že jednu politiku zvyšovanie obtiažnosti už v hre máme? Áno, je to postupné znižovanie životnosti krmiva z 10 na 5.

Pokročí ďalej, otvoríme triedu Chicken.java a do deklaráciou doplňme tri premenné typu float:

private float energy, energyAccelerator, counter;

Na konci konstruktoru urobme ich inicializáciu:

this.energy = 100;
this.energyAccelerator = 1;
this.counter = 0;

Ďalej do triedy pridáme ďalšie metódy, umiestnime treba pod existujúcu metódu update (...):

private void updateEnergy(float delta) {
    if (energy-delta < 0)
        energy = -0.1f;
    else
        energy -= delta * energyAccelerator;
}

private void updateAccelerator(float delta) {
    if (counter+delta > 50) {
        energyAccelerator += 0.2f;
        counter = 0;
    } else {
        counter+=delta;
    }
}

public void restart() {
    this.wholeSpeed = 50;
    this.dividedSpeedX = dividedSpeedY = 0;
    this.standingState = StandingState.STANDRIGHT;
    this.movingState = MovingState.RIGHT;
    this.xPositionAchieved = this.yPositionAchieved = true;
    this.positionX = SCREEN_BOUND_BEGIN.x + 200;
    this.positionY = SCREEN_BOUND_BEGIN.y + BEGINYCONSTANT + (DEMANDED_SCREEN.y - BEGINYCONSTANT) / 2 - (HEIGHT / 2);
    this.rectForOverlap.set(positionX, positionY, this.WIDTH, this.HEIGHT);
    this.energy = 100;
    this.energyAccelerator = 1;
    this.counter = 0;
}

public float getEnergy() {
    return energy;
}

public void incrEnergy() {
    if ((this.energy + 10) > 100)
        energy = 100;
    else
        this.energy += 10;
}

Dve privátne metódy updateEnergy (...) a updateAccelerator (...) musíme ešte zavolať, to vykonáme na úplnom konci metódy update (...):

updateEnergy(delta);
updateAccelerator(delta);

Samozrejme, že by nemuseli vôbec existovať, ich veľmi primitívne kód pokojne môžete napísať do metódy update (...), chcel som ich názvom vyjadriť, čo ich kód robí, išlo by to samozrejme vyjadriť tiež komentárom. Robia teda postupné zvyšovanie obtiažnosti hry, ktorú sme si už vysvetlili vyššie. Procedúra reštart () zabezpečí nastavenie atribútov na počiatočné predvolené hodnoty pri novej hre. Triedu uložíme a zatiaľ môžeme zatvoriť.

Energiu kurčaťa si grafickú formou "progress baru" premietneme na obrazovku, otvoríme si triedu Renderer.java a napríklad pod metódu render (...) si pridáme novú metódu:

private void drawEnergyBar() {
    shapeRenderer.begin(ShapeType.Filled);
    if (chicken.getEnergy() <= 25)
        shapeRenderer.setColor(1, 0, 0, 1);
    else
        shapeRenderer.setColor(1, 1.0f, 0, 1);
    shapeRenderer.rect(screenBoundBegin.x + demandedScreen.x - 20, screenBoundBegin.y + 5 + 100, 15, -chicken.getEnergy());
    shapeRenderer.end();
    shapeRenderer.begin(ShapeType.Line);
    shapeRenderer.setColor(1, 0, 0, 1);
    shapeRenderer.rect(screenBoundBegin.x + demandedScreen.x - 20, screenBoundBegin.y + 5,15 , 100);
    shapeRenderer.end();
}

Aby sa nám ukazovateľ energie zobrazil, vykonáme zavolanie tejto novej metódy na konci funkcie render (...), prikladám súčasný výpis celej funkcie:

public void render(float delta) {
    Gdx.gl.glClearColor(0, 0, 0, 1);    // black background reduce flashing
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batcher.begin();
    //batcher.enableBlending(); //!!!!!!pruhlednost
    batcher.draw(rBackground,screenBoundBegin.x, screenBoundBegin.y, demandedScreen.x, demandedScreen.y); //pozadi
    drawTextScore();
    drawTextSpeed();
    drawTextFood();
    drawFood();
    drawChicken(delta);
    batcher.end();
    drawEnergyBar();
}

Pridáme importy, triedu uložíme a môžeme zatvoriť.

Teraz potrebujeme po každom nakŕmení sliepky zvýšiť jej energiu, to vykonáme volaním metódy chicken.incrEnergy () pri každom kŕmení. Otvoríme triedu OverlapsManager­.java a do jej metódy update (...) toto volanie metódy pridáme, takže výsledná podoba metódy bude:

public void update(float delta) {   // trida hlida, zda se instance food a chicken protinaji!

    if (Intersector.overlaps(food.getRectForOverlap(),chicken.getRectForOverlap()) && food.getWasClicked() && (!food.getWasCounted()) && chicken.isStanding())
    {
        score[0]++;
        food.setWasCounted(true);
        chicken.incrEnergy();
        if (chicken.getStandingState() == StandingState.STANDLEFT || chicken.getStandingState()==StandingState.STANDRIGHT) {
            if (chicken.getStandingState() == StandingState.STANDLEFT)
                chicken.setStandingState(StandingState.EATLEFT);
                else
                chicken.setStandingState(StandingState.EATRIGHT);
                }
        }
    }
}

Drobnú zmenu vo forme pridanie jedného riadku uložíme a môžeme zatvoriť.

Ukladanie dát

Ideme na druhú časť dnešného dielu. Knižnica libGDX poskytuje veľmi jednoduché API pre ukladanie dát malého obsahu na úložisko, ktoré sa nazýva Preferences. Čítanie alebo zápis vykonávame pomocou kľúča. Takto jednoduchú vec asi nemá zmysel nejako popisovať, rovno si to ukážeme na okomentované kódu. Otvoríme triedu AssetManager.java, kde k existujúcim deklaráciám premenných pridáme:

public static Preferences prefs;

a na koniec metódy load (), pod existujúce inicializácia zvukov, pridáme:

// Vytvor (nebo obdrz existujici) soubor
prefs = Gdx.app.getPreferences("wackychicken");

// Existuje v mem souboru klic? Pokud ne, vloz ho s vychozi hodnotou 0
if (!prefs.contains("highScore")) {
    prefs.putInteger("highScore", 0);
}

Ďalej si do nášho manažéra zdrojov pridáme dve metódy, umiestnime ich napríklad pod existujúcu metódu load ():

// Uloz ke klici highScore predanou hodnotu
public static void setHighScore(int val) {
    prefs.putInteger("highScore", val);
    prefs.flush();
}

// Ziskej ke klici highScore ulozenou hodnotu
public static int getHighScore() {
    return prefs.getInteger("highScore");
}

Ako to funguje je zrejmé z komentárov. Proste, keď budeme chcieť prečítať z úložiska hodnotu high score, tak si zavoláme metódu getHighScore (). Ak budeme chcieť nové high score uložiť, zavoláme metódu setHighScore (...) s hodnotou skóre v odovzdanom argumentu. Nič viac nás ohľadom úložiska nemusí zaujímať :) . Pridáme importy, triedu uložíme a môžeme zatvoriť.

To je pre dnešok všetko, nášho dnešného cieľa sme dosiahli. Prístup do úložiska máme. Ukazovateľ energie nám funguje, pri kŕmení sa dobije a pomaly sa znižuje až do nulových hodnôt.

Nabudúce na ukazovateľ energie nadviažeme, kedy zaistíme, aby pri nulovej hodnote energie kurčaťa hra skončila. Inak povedané, aby došlo k prepnutiu herného stavu na GameOver.

 

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é 20x (6.27 MB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Programujeme Android hru - Animácie, zvuky
Všetky články v sekcii
Programujeme Android hru
Preskočiť článok
(neodporúčame)
Programujeme Android hru - Jednoduchá herné slučka
Č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