9. diel - Programujeme Android hru - Assets load
Po dlhšej odmlke som konečne našiel nejaký čas a chuť napísať ďalší diel nášho kurzu. V dnešnom diele by sme implementovali načítanie zdrojov (obrázkov a animácií) z disku do pamäte aplikácie. Obrázky sliepky a kŕmenie som kúpil na webe https://www.iconfinder.com. Pozadie som potom pod free licenciou stiahol z adresy http://www.clker.com. Úpravy všetkých obrázkov tu použitých som robil v GIMPu.
Začneme pridaním obrázkov do našej projektovej zložky. Máme dve možnosti ako to urobiť.
Prvou možnosťou je, že priamo v Eclipse, v našej projektovej troch-priečinku, rozkliknite wacky-chicken-android, v nej klikneme pravým tlačidlom myši na podpriečinok assets, objaví sa nám ponuka, v ktorej vyberieme položku Import ...
Ďalej v zložke General vyberieme položku File System:
A v poslednej ponuke vyberieme súbory s našimi obrázkami, ktoré chceme do projektu pridať:
Druhou možnosťou je nakopírovaniu obrázkov priamo do zložky na disku,
kde máme náš projekt umiestnený
...\workspace\wackychicken\android\assets
. V tomto prípade musíme
v Eclipse, ako už bolo spomenuté vyššie, kliknúť pravým tlačidlom myši
na podpriečinok assets a vybrať položku Refresh. Obrázky teda máme, teraz
je potrebujeme pri spustení našej hry načítať do pamäte. Načítanie
všetkých zdrojov obstará nami už vytvorená trieda AssetManager, poďme v
nej naše súbory s obrázkami obslúžiť:
package com.wackychicken.managers; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.g2d.Animation; import com.badlogic.gdx.graphics.g2d.TextureRegion; public class AssetManager { public static Texture background; public static Texture left1,left2,leftSideDown1,leftSideDown2,leftSideUp1,leftSideUp2; public static Texture right1,right2,rightSideDown1,rightSideDown2,rightSideUp1,rightSideUp2; public static Texture standLeft12; //animace oka public static TextureRegion rStandLeft1,rStandLeft2; //animace oka public static Animation standLeftAnime; //animace oka public static Texture standRight12; //animace oka public static TextureRegion rStandRight1,rStandRight2; //animace oka public static Animation standRightAnime; //animace oka public static void load() { background = new Texture(Gdx.files.internal("background.png")); background.setFilter(TextureFilter.Nearest, TextureFilter.Nearest); //proti rozmazavani pri roztahovani 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*/ } }
Triedu AssetManager.java, vyplnenú kódom vyššie, uložíme. Importy pridávať nemusíme, v tomto prípade som nechal importy vypísané v kóde. Prepáčte za dlhý kód, musel som aspoň animovať žmurkanie oka sliepky, aby nevyzerala ako mŕtvola, keď práve stojí na mieste. Tiež potrebujeme, aby sa aspoň trochu nakláňala - rotovala podľa toho, akým smerom ide.
K opisu triedy: nemá konštruktor, má iba jednu statickú funkciu load (), ktorá nahrá všetky zdroje (obrázky, animácie, zvuky) do pamäte, má iba verejné statické premenné. Podľa tejto triedy nevytvárame žiadnu inštanciu, je to mätúce a možno si niekto povie proti zásadám OOP, súhlasím. (Ne) výhodou statických premenných je to, sú viazané na triedu samotnú, nie na jej inštanciu (e), takže nemusíme odovzdávať žiadny odkaz inštancie ďalej, proste odkiaľkoľvek pristúpime cez verejnú triedu AssetManager rovno k jej statické premenné.
K použitým triedam: Texture sú len obrázky uložené v pamäti, nič viac. TextureRegion je vybraná oblasť z Texture určenú súradnicami. Správne by sa to malo asi robiť tak, že do pamäti načítame jeden veľký obrázok, ktorý bude obsahovať všetky jednotlivé obrázky použité v hre a potom pomocou súradníc z tohto veľkého obrázka získame všetky jednotlivé obrázky. Mne sa ale nechcelo toľko pracovať s tými súradnicami (neustále odmeriavať), tak mám veľa jednotlivých súborov obrázkov. Ako zdroj pre animácie nemožno Texture použiť, zdrojom pre animácie musia byť dve a viac TextureRegion alebo pole TextureRegion [], ako argumenty konstruktoru pri vzniku novej animácie odovzdávam float číslo udávajúce čas trvania jednej snímky a odkaz na pole TextureRegion [], ktoré chcem premietnuť. Metóda setPlayMode (Animation.PlayMode.XXX) nastavuje, akým spôsobom sa majú jednotlivé snímky prehrávať, napr. Ako film od začiatku do konca a znova od začiatku, alebo až sa dostane na koniec, premietať odzadu na začiatok.
Už potrebujeme len pri spustení našej aplikácie zavolať funkciu load (). Otvoríme si triedu WackyChicken.java a do jej metódy create () pridáme dva riadky kódu, metóda create () bude vyzerať nasledovne:
@Override public void create () { Gdx.app.log("WackyChicken", "started Libgdx"); AssetManager.load(); Gdx.app.log("WackyChicken", "Assets loaded!"); setScreen(new GameScreen()); }
Pridáme importy, uložíme a skúsime spustiť. Ak sa vám to rozbehlo, vidíte rovnaké okno s obdĺžniky ako v minulom diele:
A v Eclipse v Consoli sa vypísalo "Assets loaded!", Tak sa zdroje úspešne nahrali. Pre dnešok je to všetko a nabudúce sľubujem, že nahrané zdroje konečne zobrazíme. Zdrojový kód priložený.
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é 33x (373.27 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java