11. díl - Programujeme Android hru - Grafika II

Java Android Programujeme hru Programujeme Android hru - Grafika II

Jak tedy pomocí metody turnChicken(int x,int y) provádíme natáčení kuřete?

Představme si, že máme souřadnicovou soustavu podobnou té kartézské. Úmyslně zdůrazňuji podobnou, protože v naší virtuální obrazovce máme pod osou x na ose y kladné hodnoty. Ostatní parametry naší soustavy již definici kartézské soustavy vyhovují: osy jsou vzájemně kolmé, jednotky na nich mají stejnou velikost (vzdálenost v px), počátek soustavy je v bodě [0,0].

Jak to tedy funguje? Obrázek nám řekne více než mnoho slov:

Přenesené souřadnice
  1. Odečtením souřadnic kuřete od souřadnic kliku uživatele posuneme souřadnice kuřete do počátku souřadnicového systému - tedy do bodu [0,0] a o tuto stejnou vzdálenost zároveň posuneme souřadnice kliku uživatele.
  2. Spočítáme proměnnou rt (zkratka ratio) stejným způsobem jako sinus v pravoúhlém trojúhelníku. Úmyslně jsem proměnnou nepojmenoval sinus, protože tím, že nejsme v kartézské soustavě - máme jinak osu y, by znaménka neodpovídala jednotlivým kvadrantům.
  3. Dle hodnoty proměnné rt a zároveň dle toho, zda proměnná transformedPo­sitionX je menší nebo větší než nula, určíme úhel a směr rotace slepice.

Pojďme konečně promítat, otevřeme si třídu Renderer.java, kterou máme vyplněnou z 8. dílu tak, že se nám zobrazuje místo slepice žlutý obdélník. Abychom neduplikovali text, třídu rovnou vyplníme do níže uvedeného tvaru a příště si vše vysvětlí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();
        }
}

Přidáme importy a třídu uložíme. Nevyužitou BEGINYCONSTANT máme na příště. Vyběhla na nás chyba, že v AssetManageru není proměnná rBackground, otevřeme tedy AssetManager.java a pod stávající deklaraci proměnné

public static Texture background

přidáme:

public static TextureRegion rBackground;

Dále tuto proměnnou inicializujeme. Do funkce load() pod stávající řádky

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

přidáme:

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

Třídu uložíme a zavřeme.

Ještě jsem zapomněl v konstruktoru třídy Chicken.java inicializovat stavové proměnné movingState a standingState, proto si tuto třídu otevřeme a na konec konstruktoru doplníme:

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

Nevyužité konstanty DEMANDED_SCREEN si zatím nevšímáme. Změnu uložíme a třídu zavřeme. Pro dnešek máme hotovo. Kdyby bylo cokoli nejasné, můžete opisovat z přiloženého zdrojového kódu, který je ke stažení. Aplikaci spustíme.

Kuře se naklání

Vidíme, že nám vše funguje, slepice jde správným směrem na místo kliku a také se naklání.


 

Stáhnout

Staženo 9x (6.07 MB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

  Aktivity (3)

Článek pro vás napsal Jaroslav Polívka
Avatar
Autor se věnuje převážně jazykům JAVA a C++

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 


Miniatura
Všechny články v sekci
Programujeme Android hru
Miniatura
Následující článek
Programujeme Android hru - Krmení I

 

 

Komentáře

Avatar
vodacek
Redaktor
Avatar
vodacek:

proč tolik textur? proč nejsou v atlasu? proč to není jen 1 obrázek, který se natáčí?

 
Odpovědět 21. listopadu 20:32
Avatar
Jaroslav Polívka:

Obrázky bych musel pospojovat do jednoho souboru a pak je pomocí souřadnic načítat, nechci pracovat tolik se souřadnicemi. Natáčení mě taky napadlo, ale chtěl jsem ještě mihotat packama kuřete.

Odpovědět  +1 22. listopadu 18:53
Velice často si věci žijí svým životem
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.