Lekce 9 - Programujeme Android hru - Assets load
V předchozí lekci, Programujeme Android hru - Rozdělení hry do tříd II, jsme pokračovali v implementaci tříd.
Po delší odmlce jsem konečně našel nějaký čas a chuť napsat další díl našeho kurzu. V dnešním díle bychom implementovali načtení zdrojů (obrázků a animací) z disku do paměti aplikace. Obrázky slepice a krmení jsem koupil na webu https://www.iconfinder.com. Pozadí jsem potom pod free licencí stáhl z adresy http://www.clker.com. Úpravy všech obrázků zde použitých jsem dělal v GIMPu.
Začneme přidáním obrázků do naší projektové složky. Máme dvě možnosti jak to udělat.
První možností je, že přímo v Eclipse, v naší projektové tří-složce, rozklikneme wacky-chicken-android, v ní klikneme pravým tlačítkem myši na podsložku assets, objeví se nám nabídka, ve které vybereme položku Import...

Dále ve složce General vybereme položku File System:

A v poslední nabídce vybereme soubory s našimi obrázky, které chceme do projektu přidat:

Druhou možností je nakopírování obrázků přímo do složky na disku,
kde máme náš projekt umístěný
...\workspace\wackychicken\android\assets
. V tomto případě
musíme v Eclipse, jak již bylo zmíněno výše, kliknout pravým tlačítkem
myši na podsložku assets a vybrat položku Refresh. Obrázky tedy máme, nyní
je potřebujeme při spuštění naší hry načíst do paměti. Načtení
všech zdrojů obstará námi již vytvořená třída AssetManager, pojďme v
ní naše soubory s obrázky obsloužit:
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*/ } }
Třídu AssetManager.java, vyplněnou kódem výše, uložíme. Importy přidávat nemusíme, v tomto případě jsem nechal importy vypsané v kódu. Promiňte za dlouhý kód, musel jsem alespoň animovat mrkání oka slepice, aby nevypadala jako mrtvola, když zrovna stojí na místě. Také potřebujeme, aby se alespoň trochu nakláněla - rotovala podle toho, jakým směrem jde.
K popisu třídy: nemá konstruktor, má pouze jednu statickou funkci load(), která nahraje všechny zdroje (obrázky, animace, zvuky) do paměti, má pouze veřejné statické proměnné. Podle této třídy nevytváříme žádnou instanci, je to matoucí a možná si někdo řekne proti zásadám OOP, souhlasím. (Ne)výhodou statických proměnných je to, jsou vázány na třídu samotnou, nikoli na její instanci(e), takže nemusíme předávat žádný odkaz instance dále, prostě odkudkoli přistoupíme přes veřejnou třídu AssetManager rovnou k její statické proměnné.
K použitým třídám: Texture jsou jen obrázky uložené v paměti, nic víc. TextureRegion je vybraná oblast z Texture určená souřadnicemi. Správně by se to mělo asi dělat tak, že do paměti načteme jeden velký obrázek, který bude obsahovat všechny jednotlivé obrázky použité ve hře a poté pomocí souřadnic z tohoto velkého obrázku získáme všechny jednotlivé obrázky. Mně se ale nechtělo tolik pracovat s těmi souřadnicemi (neustále odměřovat), tak mám hodně jednotlivých souborů obrázků. Jako zdroj pro animace nelze Texture použít, zdrojem pro animace musí být dvě a více TextureRegion nebo pole TextureRegion[], jako argumenty konstruktoru při vzniku nové animace předávám float číslo udávající čas trvání jednoho snímku a odkaz na pole TextureRegion[], které chci promítnout. Metoda setPlayMode(Animation.PlayMode.XXX) nastavuje, jakým způsobem se mají jednotlivé snímky přehrávat, např. jako film od začátku do konce a znovu od začátku, nebo až se dostane na konec, promítat pozpátku na začátek.
Již potřebujeme jen při spuštění naší aplikace zavolat funkci load(). Otevřeme si třídu WackyChicken.java a do její metody create() přidáme dva řádky kódu, metoda create() bude vypadat následovně:
@Override public void create () { Gdx.app.log("WackyChicken", "started Libgdx"); AssetManager.load(); Gdx.app.log("WackyChicken", "Assets loaded!"); setScreen(new GameScreen()); }
Přidáme importy, uložíme a zkusíme spustit. Pokud se vám to rozjelo, vidíte stejné okno s obdélníky jako v minulém díle:

A v Eclipse v Consoli se vypsalo "Assets loaded!", tak se zdroje úspěšně nahrály. Pro dnešek je to vše.
Napříště, Programujeme Android hru - Grafika I, slibuji, že nahrané zdroje konečně zobrazíme. Zdrojový kód přiložen.
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 33x (373.27 kB)
Aplikace je včetně zdrojových kódů v jazyce Java