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