10. díl - Programujeme Android hru - Grafika I

Java Android Programujeme hru Programujeme Android hru - Grafika I

V minulém díle našeho seriálu jsme načetli grafické zdroje pozadí a slepice. V dnešním dvoj-díle je promítneme na obrazovku.

Půjde o velmi jednoduché promítání, slepice bude mít následující možnosti směrů chůzí a rotací:

  • chůze vlevo, rotace vlevo
  • chůze vpravo, rotace vpravo
  • chůze dolů, rotace vlevo
  • chůze dolů, rotace vpravo
  • chůze vzhůru, rotace vlevo
  • chůze vzhůru, rotace vpravo
  • chůze a rotace šikmo vpravo vzhůru
  • chůze a rotace šikmo vpravo dolů
  • chůze a rotace šikmo vlevo dolů
  • chůze a rotace šikmo vlevo vzhůru
Varianty pohybů a otočení

Ke každé možnosti je vázána sada dvou obrázků, které promítneme střídavě na obrazovku, abychom vytvořili alespoň základní iluzi chůze slepice.

Náš kód vybere jednu z možností na základě výpočtu, který objasním dále. Nesmím zapomenout zdůraznit, že možnosti chůzí pouze čistě vlevo, vpravo, vzhůru a dolů málokdy existují. Slepice se většinou pohybuje více či méně po obou osách současně - tedy šikmo. My to ale uděláme tak, že pohyby v mírně šikmých směrech budeme považovat za pohyby čistě vlevo, vpravo, dolů nebo vzhůru. Jinak řečeno, při mírně šikmých pohybech nebudeme slepici naklánět vůbec.

Různé možnosti promítnutí podle aktuální pozice slepice a kliku uživatele na obrazovku nejsou ničím jiným, než vlastnostmi naší slepice. Otevřeme si třídu Chicken.java a pomocí výčtových konstant tyto vlastnosti slepici přidáme. Pod stávající proměnné si přidáme další:

public enum MovingState{LEFT,LEFTUP,LEFTDOWN,LEFTSIDEDOWN,LEFTSIDEUP,
                        RIGHT,RIGHTUP,RIGHTDOWN,RIGHTSIDEDOWN,RIGHTSIDEUP}

public enum StandingState{STANDLEFT,STANDRIGHT,EATLEFT,EATRIGHT}

private MovingState movingState;
private StandingState standingState;

Dále si k těmto proměnným přidáme přístupové metody:

public MovingState getMovingState() {
        return movingState;
}

public void setMovingState(MovingState state) {
        movingState=state;
}

public StandingState getStandingState() {
        return standingState;
}

public void setStandingState(StandingState state) {
        standingState=state;
}

Vložíme je třeba na konec třídy, pod stávající přístupové metody. Třídu uložíme a můžeme zavřít. Výpis celé třídy nyní dělat nebudu, v případě potřeby se podívejte do přiloženého zdrojového kódu, který je ke stažení.

Co potřebujeme dále? Vždy, když uživatel klikne na obrazovku, potřebujeme určit a nastavit do jakého směru se má slepice natočit. To nám zajistí naše třída TurnManager.java, do které jsem pro tento účel přidal metodu turnChicken(int x,int y), jejími argumenty jsou souřadnice místa kliku uživatele na obrazovku. Upravme naší třídu TurnManager.java do níže uvedené podoby:

public class TurnManager {

        private MovingState movingState;
        private StandingState standingState;
        private Chicken chicken;
        private final Vector2 screenBoundEnd;
        private final Vector2 screenBoundBegin;
        private final int BEGINYCONSTANT;

        public TurnManager(GameScreen gameScreen,final int BEGINYCONSTANT) {
                final Vector2 demandedScreen=gameScreen.DEMANDED_SCREEN;
                this.screenBoundBegin=gameScreen.SCREEN_BOUND_BEGIN;
                this.screenBoundEnd=gameScreen.SCREEN_BOUND_END;
                this.BEGINYCONSTANT=BEGINYCONSTANT;
                this.chicken = new Chicken(screenBoundBegin,screenBoundEnd,demandedScreen,BEGINYCONSTANT);
        }

        public void turnChicken(int x,int y) {
                // x a y souradnice kliku
                float transformedPositionX = x - chicken.getPositionX() - chicken.getWidth()/2;
                float transformedPositionY = y - chicken.getPositionY() - chicken.getHeight()/2;
                double rt = transformedPositionY /  Math.sqrt( (Math.pow(transformedPositionX,2) + Math.pow(transformedPositionY,2)) );
                // Gdx.app.log("turnMng rt:", ""+rt);

                if ((rt < -0.9) && (transformedPositionX <= 0))
                {
                        movingState=MovingState.LEFTUP;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDLEFT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt < -0.9) && (transformedPositionX > 0))
                {
                        movingState=MovingState.RIGHTUP;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDRIGHT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt >= -0.9 ) && (rt <= -0.4) && (transformedPositionX > 0))
                {
                        movingState=MovingState.RIGHTSIDEUP;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDRIGHT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt > -0.4)  && (rt < 0.4)  && (transformedPositionX > 0))
                {
                        movingState=MovingState.RIGHT;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDRIGHT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt >= 0.4) && (rt <= 0.9 ) && (transformedPositionX > 0))
                {
                        movingState=MovingState.RIGHTSIDEDOWN;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDRIGHT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt > 0.9) && (transformedPositionX <= 0))
                {
                        movingState=MovingState.LEFTDOWN;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDLEFT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt > 0.9) && (transformedPositionX > 0))
                {
                        movingState=MovingState.RIGHTDOWN;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDRIGHT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt <= 0.9 )  && (rt >= 0.4) && (transformedPositionX < 0))
                {
                        movingState=MovingState.LEFTSIDEDOWN;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDLEFT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt < 0.4) &&  (rt > -0.4) && (transformedPositionX < 0))
                {
                        movingState=MovingState.LEFT;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDLEFT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else if ((rt <= -0.4) && (rt >= -0.9) && (transformedPositionX < 0))
                {
                        movingState=MovingState.LEFTSIDEUP;
                        chicken.setMovingState(movingState);
                        standingState=StandingState.STANDLEFT;
                        chicken.setStandingState(standingState);
                        //Gdx.app.log("turnMng state:",chicken.getMovingState().toString());
                }
                else Gdx.app.log("turnMng:", "chybna hodnota rt");
        } //konec turnChicken

        public void setChickenDistance(int x, int y) {
                int clickedPositionX=x,clickedPositionY=y;
                float distanceX,distanceY;
                float chickenTailX = chicken.getPositionX() + chicken.getWidth();
                if (Math.abs(clickedPositionX - chicken.getPositionX()) <= Math.abs(clickedPositionX - chickenTailX))
                        distanceX = clickedPositionX - chicken.getPositionX();
                else
                        distanceX=clickedPositionX - chickenTailX;
                if(distanceX < screenBoundBegin.x-chicken.getPositionX())
                        distanceX = screenBoundBegin.x-chicken.getPositionX();
                if(distanceX > screenBoundEnd.x- chickenTailX)
                        distanceX=screenBoundEnd.x- chickenTailX;

                distanceY=clickedPositionY-(chicken.getPositionY()+chicken.getHeight());
                if(distanceY < (screenBoundBegin.y+BEGINYCONSTANT)-(chicken.getPositionY()+ chicken.getHeight()))
                        distanceY=(screenBoundBegin.y+BEGINYCONSTANT)-(chicken.getPositionY()+ chicken.getHeight());
                if(distanceY > (screenBoundEnd.y-(chicken.getPositionY()+chicken.getHeight())) )
                        distanceY = screenBoundEnd.y-(chicken.getPositionY()+chicken.getHeight());

                if(Math.abs(distanceX)<0.5f)
                {
                        if(distanceX >=0) distanceX=0.5f;
                                else distanceX=-0.5f;
                }

                if(Math.abs(distanceY)<0.5f)
                {
                        if(distanceY >=0) distanceY=0.5f;
                                else distanceY=-0.5f;
                }

                chicken.setDistanceX(distanceX);
                chicken.setDistanceY(distanceY);
        }


        public void setChickenSpeed() {
                float speedRatio = chicken.getWholeSpeed() / (Math.abs(chicken.getDistanceX()) + Math.abs(chicken.getDistanceY()));

                chicken.setDividedSpeedX(speedRatio*chicken.getDistanceX());
                chicken.setDividedSpeedY(speedRatio*chicken.getDistanceY());
        }

        public Chicken getChicken() {   // kvuli objMng
                return chicken;
        }
}

Přidáme importy, třídu uložíme a můžeme zavřít. Naší novou metodu turnChicken(int x, int y) nezapomeneme zavolat. Otevřeme si třídu ObjectManager.java a do její metody receivePosition(int x,int y) přidáme volání, takže výsledná podoba metody bude:

public void receivePosition(int x,int y) { //souradnice z inputu
        turnMng.turnChicken(x, y);
        turnMng.setChickenDistance(x, y);
        turnMng.setChickenSpeed();
        chicken.setXPositionAchieved(false);
        chicken.setYPositionAchieved(false);
}

Tímto zavoláním nám metoda turnChicken(int x,int y) po kliku uživatele na obrazovku nastaví stavové proměnné kuřete movingState a standingState, kterými následně budeme řídit promítačku. Příště budeme pokračovat objasněním principu funkce turnChicken(int x,int y).


 

Stáhnout

Staženo 3x (12.54 kB)
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?
Celkem (2 hlasů) :
4.54.54.54.54.5


 


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

 

 

Komentáře

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.

Zatím nikdo nevložil komentář - buď první!