Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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 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...

Eclipse – android-assets - Programujeme Android hru

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

Eclipse – File System - Programujeme Android hru

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

Eclipse – Android File System - Programujeme Android hru

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(A­nimation.Play­Mode.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:

hra v Javě pro Android – Assets loaded! - Programujeme Android hru

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 32x (373.27 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Programujeme Android hru - Rozdělení hry do tříd II
Všechny články v sekci
Programujeme Android hru
Přeskočit článek
(nedoporučujeme)
Programujeme Android hru - Grafika I
Č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