IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

11. diel - Programujeme Android hru - Grafika II

Ako teda pomocou metódy turnChicken (int x, int y) vykonávame natáčania kurčaťa?

Predstavme si, že máme súradnicovú sústavu podobnú tej karteziánske. Úmyselne zdôrazňujem podobnú, pretože v našej virtuálnej obrazovke máme pod osou x na osi y kladné hodnoty. Ostatné parametre našej sústavy už definíciu karteziánske sústavy vyhovujú: osi sú vzájomne kolmé, jednotky na nich majú rovnakú veľkosť (vzdialenosť v px), počiatok sústavy je v bode [0,0].

Ako to teda funguje? Obrázok nám povie viac ako veľa slov:

prenesené súradnice - Programujeme Android hru
  1. Odpočítaním súradníc kurčaťa od súradníc kľučku užívateľa posunieme súradnice kurčaťa do začiatku súradnicového systému - teda do bodu [0,0] ao túto rovnakú vzdialenosť zároveň posunieme súradnice kľučku užívateľa.
  2. Spočítame premennú rt (skratka ratio) rovnakým spôsobom ako sínus v pravouhlom trojuholníku. Úmyselne som premennú nepomenoval sínus, pretože tým, že nie sme v kartézské sústave - máme inak os y, by znamienka nezodpovedala jednotlivým kvadrantům.
  3. Podľa hodnoty premennej rt a zároveň podľa toho, či premenná transformedPo­sitionX je menšia alebo väčšia ako nula, určíme uhol a smer rotácie sliepky.

Poďme konečne premietať, otvoríme si triedu Renderer.java, ktorú máme vyplnenú z 8. dielu tak, že sa nám zobrazuje miesto sliepky žltý obdĺžnik. Aby sme nekopíroval text, triedu rovno vyplníme do nižšie uvedeného tvaru a nabudúce si všetko vysvetlíme.

public class Renderer {

    private OrthographicCamera cam;
    private ShapeRenderer shapeRenderer;
    private SpriteBatch batcher;
    private final Vector2 demandedScreen,screenBoundBegin;
    private final GameScreen gameScreen;
    private Chicken chicken;
    private GameManager gameMng;

    private Texture left1,left2,leftSideDown1,leftSideDown2,leftSideUp1,leftSideUp2,leftUp1,leftUp2,leftDown1,leftDown2;
    private Texture right1,right2,rightSideDown1,rightSideDown2,rightSideUp1,rightSideUp2,rightUp1,rightUp2,rightDown1,rightDown2;
    private TextureRegion rBackground;
    private Animation standLeftAnime,standRightAnime;

    private int counter;
    private float runTime;
    private final int COUNTERBEGIN = 20,COUNTEREND =40, BEGINYCONSTANT;

    public Renderer(GameManager gameManager, float orthoHeight, float orthoWidth) {
        this.gameMng=gameManager;
        this.gameScreen=gameMng.getGameScreen();
        this.demandedScreen=gameScreen.DEMANDED_SCREEN;
        this.screenBoundBegin=gameScreen.SCREEN_BOUND_BEGIN;
        this.BEGINYCONSTANT=gameMng.getObjectManager().getBEGINYCONSTANT();
        this.cam = new OrthographicCamera();
        this.cam.setToOrtho(true, orthoWidth,orthoHeight);
        this.shapeRenderer = new ShapeRenderer();
        this.shapeRenderer.setProjectionMatrix(cam.combined);
        this.batcher = new SpriteBatch();
        this.batcher.setProjectionMatrix(cam.combined);

        counter=0;
        runTime=0;
        initAssetsObjects();
    }


    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
    drawChicken(delta);
    batcher.end();
    }

    private void drawChicken(float delta) {
        counter+=delta*250*(chicken.getWholeSpeed()/180); // korekce animace pri zrychlovani chicken
        if(!chicken.isStanding()) {
            if(chicken.getMovingState()==MovingState.LEFT)
            {
                if((int)counter<COUNTERBEGIN)           batcher.draw(left1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(left2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                    if((int)counter>COUNTEREND)counter=0;
                }
            }
            else if (chicken.getMovingState()==MovingState.RIGHT)
            {
                if((int)counter<COUNTERBEGIN)
                batcher.draw(right1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {           batcher.draw(right2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                    if((int)counter>COUNTEREND)
                        counter=0;
                }
            }
            else if (chicken.getMovingState()==MovingState.LEFTSIDEDOWN)
            {
                if((int)counter<COUNTERBEGIN)           batcher.draw(leftSideDown1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(leftSideDown2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                    if((int)counter>COUNTEREND)
                        counter=0;
                }
            }
            else if (chicken.getMovingState()==MovingState.LEFTSIDEUP)
            {
                if((int)counter<COUNTERBEGIN)
            batcher.draw(leftSideUp1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(leftSideUp2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>COUNTEREND)
                    counter=0;
                }
            }
            else if (chicken.getMovingState()==MovingState.RIGHTSIDEUP)
            {
                if((int)counter<COUNTERBEGIN)
            batcher.draw(rightSideUp1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(rightSideUp2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>COUNTEREND)counter=0;
                }
            }
            else if (chicken.getMovingState()==MovingState.RIGHTSIDEDOWN)
            {
                if((int)counter<COUNTERBEGIN)
            batcher.draw(rightSideDown1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(rightSideDown2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                    if((int)counter>COUNTEREND)
                        counter=0;
                }
            }
            else if(chicken.getMovingState()==MovingState.LEFTUP)
            {
                if((int)counter<COUNTERBEGIN)
            batcher.draw(leftUp1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(leftUp2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>COUNTEREND)counter=0;
                }
            }
            else if(chicken.getMovingState()==MovingState.LEFTDOWN)
            {
                if((int)counter<COUNTERBEGIN)
            batcher.draw(leftDown1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(leftDown2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>COUNTEREND)
                    counter=0;
                }
            }
            else if (chicken.getMovingState()==MovingState.RIGHTUP)
            {
                if((int)counter<COUNTERBEGIN)
            batcher.draw(rightUp1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(rightUp2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>COUNTEREND)
                    counter=0;
                }
            }
            else if (chicken.getMovingState()==MovingState.RIGHTDOWN)
            {
                if((int)counter<COUNTERBEGIN)
            batcher.draw(rightDown1,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                if((int)counter>=COUNTERBEGIN)
                {
            batcher.draw(rightDown2,chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
                    if((int)counter>COUNTEREND)
                        counter=0;
                }
            }
            else
                Gdx.app.log("renderer:", "Sem by se rizeni nemelo dostat.");
        }
        else {
            runTime+=delta; //kvuli animaci
            if(chicken.getStandingState()==StandingState.STANDLEFT)
            batcher.draw(standLeftAnime.getKeyFrame(runTime),chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());

            else if(chicken.getStandingState()==StandingState.STANDRIGHT)
            batcher.draw(standRightAnime.getKeyFrame(runTime),chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());

            else
                Gdx.app.log("renderer:", "Sem by se rizeni nemelo dostat.");
        }
    } //end of drawChicken

    private void initAssetsObjects() {
        this.rBackground=AssetManager.rBackground;
        this.right1=AssetManager.right1;
        this.right2=AssetManager.right2;
        this.rightSideDown1=AssetManager.rightSideDown1;
        this.rightSideDown2=AssetManager.rightSideDown2;
        this.rightSideUp1=AssetManager.rightSideUp1;
        this.rightSideUp2=AssetManager.rightSideUp2;
        this.rightUp1=rightDown1=AssetManager.right1;
        this.rightUp2=rightDown2=AssetManager.right2;

        this.left1=AssetManager.left1;
        this.left2=AssetManager.left2;
        this.leftSideDown1=AssetManager.leftSideDown1;
        this.leftSideDown2=AssetManager.leftSideDown2;
        this.leftSideUp1=AssetManager.leftSideUp1;
        this.leftSideUp2=AssetManager.leftSideUp2;
        this.leftDown1=leftUp1=AssetManager.left1;
        this.leftDown2=leftUp2=AssetManager.left2;

        this.standLeftAnime=AssetManager.standLeftAnime;
        this.standRightAnime=AssetManager.standRightAnime;

        this.chicken=gameMng.getObjectManager().getChicken();
    }
}

Pridáme importy a triedu uložíme. Nevyužitú BEGINYCONSTANT máme na nabudúce. Vybehla na nás chyba, že v AssetManageru nie je premenná rBackground, otvoríme teda AssetManager.java a pod existujúce deklaráciu premennej

public static Texture background

pridáme:

public static TextureRegion rBackground;

Ďalej túto premennú inicializujeme. Do funkcie load () pod existujúce riadky

background = new Texture(Gdx.files.internal("background.png"));
background.setFilter(TextureFilter.Nearest, TextureFilter.Nearest); //proti rozmazavani pri roztahovani

pridáme:

rBackground = new TextureRegion(background,0,0,800,500);
rBackground.flip(false, true);

Triedu uložíme a zatvoríme.

Ešte som zabudol v konstruktoru triedy Chicken.java inicializovať stavové premenné movingState a standingState, preto si túto triedu otvoríme a na koniec konstruktoru doplníme:

this.standingState=StandingState.STANDRIGHT;
this.movingState=MovingState.RIGHT;

Nevyužité konštanty DEMANDED_SCREEN si zatiaľ nevšímame. Zmenu uložíme a triedu zatvoríme. Pre dnešok máme hotovo. Keby bolo čokoľvek nejasné, môžete opisovať z priloženého zdrojového kódu, ktorý je k stiahnutiu. Aplikáciu spustíme.

Kurča sa nakláňa - Programujeme Android hru

Vidíme, že nám všetko funguje, sliepky ide správnym smerom na miesto kľučku a tiež sa nakláňa.


 

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 (6.07 MB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Programujeme Android hru - Grafika I
Všetky články v sekcii
Programujeme Android hru
Preskočiť článok
(neodporúčame)
Programujeme Android hru - Kŕmenie I
Článok pre vás napísal Jaroslav Polívka
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje převážně jazykům JAVA a C++
Aktivity