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 updateAccelerator(...) 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.incrEnergy() 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