IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 16 - Programujeme Android hru - Energie kuřete

V předchozí lekci, Programujeme Android hru - Animace, zvuky, jsme si objasnili volání update metod a přidali jednoduché animace a zvuky.

Dnešní díl bude takovým podkladem pro následující díl, ve kterém pomocí switch rozvětvíme provádění kódu do různých stavů hry. Například slepice chcípne = dojde jí energie, hra přejde do stavu GAMEOVER. Algoritmus obsluhy energie bude vlastně postupným zvyšováním obtížnosti hry, protože čím bude slepice "starší", tím bude potřebovat více a více krmiva, aby její energie rostla, nakonec bude odčítání proměnné tak velké, že už nebude možné slepici uživit a dojde k jejímu úhynu - konec hry. Víme, že jednu politiku zvyšování obtížnosti již ve hře máme? Ano, je to postupné snižování životnosti krmiva z 10 na 5.

Pokročme dále, otevřeme třídu Chicken.java a do deklarací doplňme tři proměnné typu float:

private float energy, energyAccelerator, counter;

Na konci konstruktoru proveďme jejich inicializaci:

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

Dále do třídy přidáme další metody, umístíme je třeba pod stávající metodu 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;
}

Dvě privátní metody updateEnergy(...) a updateAccelera­tor(...) musíme ještě zavolat, to provedeme na úplném konci metody update(...):

updateEnergy(delta);
updateAccelerator(delta);

Samozřejmě, že by nemusely vůbec existovat, jejich velmi primitivní kód klidně můžete napsat do metody update(...), chtěl jsem jejich názvem vyjádřit, co jejich kód dělá, šlo by to samozřejmě vyjádřit také komentářem. Dělají tedy postupné zvyšování obtížnosti hry, kterou jsme si již vysvětlili výše. Procedura restart() zajistí nastavení atributů na počáteční výchozí hodnoty při nové hře. Třídu uložíme a prozatím můžeme zavřít.

Energii kuřete si grafickou formou "progress baru" promítneme na obrazovku, otevřeme si třídu Renderer.java a například pod metodu render(...) si přidáme novou metodu:

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 se nám ukazatel energie zobrazil, provedeme zavolání této nové metody na konci funkce render(...), přikládám současný výpis celé funkce:

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();
}

Přidáme importy, třídu uložíme a můžeme zavřít.

Nyní potřebujeme po každém nakrmení slepice zvýšit její energii, to provedeme voláním metody chicken.incrE­nergy() při každém krmení. Otevřeme třídu OverlapsManager­.java a do její metody update(...) toto volání metody přidáme, takže výsledná podoba metody 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);
                }
        }
    }
}

Drobnou změnu ve formě přidání jednoho řádku uložíme a můžeme zavřít.

Ukládání dat

Jdeme na druhou část dnešního dílu. Knihovna libGDX poskytuje velmi jednoduché API pro ukládání dat malého obsahu na úložiště, které se nazývá Preferences. Čtení nebo zápis provádíme pomocí klíče. Takto jednoduchou věc asi nemá smysl nějak popisovat, rovnou si to ukážeme na okomentovaném kódu. Otevřeme třídu AssetManager.java, kde ke stávajícím deklaracím proměnných přidáme:

public static Preferences prefs;

a na konec metody load(), pod stávající inicializace zvuků, přidá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);
}

Dále si do našeho manažeru zdrojů přidáme dvě metody, umístíme je například pod stávající metodu 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");
}

Jak to funguje je patrné z komentářů. Prostě, když budeme chtít přečíst z úložiště hodnotu high score, tak si zavoláme metodu getHighScore(). Pokud budeme chtít nové high score uložit, zavoláme metodu setHighScore(...) s hodnotou skóre v předaném argumentu. Nic víc nás ohledně úložiště nemusí zajímat :). Přidáme importy, třídu uložíme a můžeme zavřít.

To je pro dnešek vše, našeho dnešního cíle jsme dosáhli. Přístup do úložiště máme. Ukazatel energie nám funguje, při krmení se dobije a pomalu se snižuje až do nulových hodnot.

Příště, Programujeme Android hru - Jednoduchá herní smyčka, na ukazatel energie navážeme, kdy zajistíme, aby při nulové hodnotě energie kuřete hra skončila. Jinak řečeno, aby došlo k přepnutí herního stavu na GAMEOVER.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

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

 

Předchozí článek
Programujeme Android hru - Animace, zvuky
Všechny články v sekci
Programujeme Android hru
Přeskočit článek
(nedoporučujeme)
Programujeme Android hru - Jednoduchá herní smyčka
Článek pro vás napsal Jaroslav Polívka
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
Autor se věnuje převážně jazykům JAVA a C++
Aktivity