Java týden
30 % bodů zdarma na online výuku díky naší Slevové akci!
Pouze tento týden sleva až 80 % na e-learning týkající se Javy.

Lekce 10 - Programujeme Android hru - Grafika I

V minulém díle našeho seriálu, Programujeme Android hru - Assets load, 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.

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

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ě, Programujeme Android hru - Grafika II, budeme pokračovat objasněním principu funkce turnChicken (int x,int y).


 

Stáhnout

Staženo 18x (12.54 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Programujeme Android hru - Assets load
Všechny články v sekci
Programujeme Android hru
Článek pro vás napsal Jaroslav Polívka
Avatar
Jak se ti líbí článek?
2 hlasů
Autor se věnuje převážně jazykům JAVA a C++
Aktivity (4)

 

 

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í!