8. díl - Programujeme Android hru - Rozdělení hry do tříd II

Java Android Programujeme hru Programujeme Android hru - Rozdělení hry do tříd II

Z minulé lekce kurzu o programování hry pro Android v Javě jste začali s implementací tříd a doplnili kód do tříd Chicken a TurnManager. Dnes se budeme věnovat dalším třídám.

Otevřeme třídu ObjectManager.java a vyplníme kódem:

public class ObjectManager {

        private TurnManager turnMng;
        private Chicken chicken;
        private final int BEGINYCONSTANT=180;

        public ObjectManager(GameScreen gameScreen) {
                this.turnMng=new TurnManager(gameScreen,BEGINYCONSTANT);
                this.chicken=turnMng.getChicken();
        }

        public void update(float delta) {
                chicken.update(delta);
        }

        public void receivePosition(int x,int y) { // souradnice z inputu

                turnMng.setChickenDistance(x, y);
                turnMng.setChickenSpeed();

                chicken.setXPositionAchieved(false);
                chicken.setYPositionAchieved(false);
        }


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


        public final int getBEGINYCONSTANT(){   // kvuli render
                return BEGINYCONSTANT;
        }

}

Přidáme importy a uložíme. Zde není co popisovat, jen zmíním, že metodu receivePosition() zavoláme z instance třídy InputManager.java vždy při dotyku uživatele na obrazovku, metoda předá souřadnice dotyku instanci turnMng, která:

  • nastaví kuřeti vzdálenost, kterou musí na obrazovce urazit
  • rozdělí kuřeti celkovou rychlost do proměnných dividedSpeedX a dividedSpeedY
  • v budoucnu bude rotovat slepici do požadovaného úhlu

Pokračujme, otevřeme třídu GameManager.java a okopírujeme do ní následující:

public class GameManager {

        private ObjectManager objectManager;
        private GameScreen gameScreen;
        private Chicken chicken;

        public GameManager(GameScreen gameScreen) {
                this.gameScreen=gameScreen;
                this.objectManager = new ObjectManager(gameScreen);
                this.chicken=objectManager.getChicken();
        }

        public void update(float delta) {
                objectManager.update(delta);
        }

        public ObjectManager getObjectManager() { // kvuli input manager
                return objectManager;
        }

        public GameScreen getGameScreen() { // kvuli render
                return this.gameScreen;
        }

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

}

Přidáme importy a uložíme. Musíme ještě zařídit uživatelský vstup, proto otevřeme třídu InputManager.java a vyplníme do ní:

public class InputManager implements InputProcessor{

        private ObjectManager objectManager;
        private float scaleRatioX,scaleRatioY;
        private GameManager gameManager;
        private GameScreen gameScreen;

        public InputManager(GameManager gameManager,GameScreen gameScreen,float scaleRatioX,float       scaleRatioY) {

                this.gameManager=gameManager;
                this.objectManager=gameManager.getObjectManager();
                this.scaleRatioX=scaleRatioX;
                this.scaleRatioY=scaleRatioY;
                this.gameScreen=gameScreen;
        }

        @Override
        public boolean keyDown(int keycode) {
                // TODO Auto-generated method stub
                return false;
        }

        @Override
                public boolean keyUp(int keycode) {
                // TODO Auto-generated method stub
                return false;
        }

        @Override
        public boolean keyTyped(char character) {
                // TODO Auto-generated method stub
                return false;
        }

        @Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button) {

                screenX=scaleX(screenX);
                screenY=scaleY(screenY);
                //Gdx.app.log("Inputmng touchDown x:", "" + screenX);
                //Gdx.app.log("Inputmng touchDown y:", "" + screenY + "\n");
                objectManager.receivePosition(screenX, screenY);
                return false;
        }

        @Override
        public boolean touchUp(int screenX, int screenY, int pointer, int button) {
                screenX=scaleX(screenX);
                screenY=scaleY(screenY);
                return false;
        }

        @Override
        public boolean touchDragged(int screenX, int screenY, int pointer) {
                // TODO Auto-generated method stub
                return false;
        }

        @Override
                public boolean mouseMoved(int screenX, int screenY) {
                // TODO Auto-generated method stub
                return false;
        }

        @Override
                public boolean scrolled(int amount) {
                // TODO Auto-generated method stub
                return false;
        }

        private int scaleX(int screenX){
                return (int)(screenX / scaleRatioX);
        }

        private int scaleY(int screenY){
                return (int)(screenY / scaleRatioY);
        }

}

Přidáme importy a uložíme. Třídě se v konstruktoru předávají parametry scaleRatioX a scaleRatioY, které vyjadřují poměr mezi skutečnými a virtuálními pixely obrazovky. Stejně jako jsme nastavili na fyzickou obrazovku obrazovku virtuální s nějakým poměrem, musíme se stejným poměrem přizpůsobit i uživatelský vstup, protože InputManager sbírá souřadnice z fyzické obrazovky, které většinou neodpovídají souřadnicím na obrazovce virtuální. K tomuto přizpůsobení slouží privátní metody scaleX() a scaleY(). Ostatní @Override metody jsou vestavěné a reagují na uživatelský vstup, přičemž nás v tuto chvíli zajímá metoda touchDown(), která je volána vždy, když se uživatel dotkne obrazovky.

Poslední třídu, kterou dnes budeme dělat, je promítačka. Otevřeme třídu Renderer.java a vyplníme:

public class Renderer {

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


        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.chicken=gameMng.getChicken();
                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);
        }


        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.end();

                shapeRenderer.begin(ShapeType.Filled);
                shapeRenderer.setColor(0,0.7f,0,1);
                shapeRenderer.rect(screenBoundBegin.x, screenBoundBegin.y+BEGINYCONSTANT,
                demandedScreen.x, demandedScreen.y-BEGINYCONSTANT); // trava

                shapeRenderer.setColor(1,1,0,1);
                shapeRenderer.rect(chicken.getPositionX(),chicken.getPositionY(),
                chicken.getWidth(),chicken.getHeight()); // slepice
                shapeRenderer.end();
        }

}

Přidáme importy a uložíme. Pomocí metody render() vykreslujeme dva obdélníky - jeden zelený, ten reprezentuje trávu (plochu), po které se bude moci slepice pohybovat. Druhý, žlutý, který nám dočasně nahrazuje grafiku slepice. Objekt batcher máme připravený pro budoucí díly semináře.

Třídy jsme sice nadefinovali, ale nevytvořili jsme zatím všechny jejich instance - jdeme na to. Otevřeme třídu GameScreen.java a pod stávající proměnné přidáme nové:

private GameManager gameManager;
private Renderer renderer;

V konstruktoru pod nastavením virtuální obrazovky (pod else větev) provedeme jejich inicializace + inicializaci inputManageru:

gameManager = new GameManager(this);
InputManager inputManager = new InputManager(gameManager,this,w/orthoWidth,h/orthoHeight);
Gdx.input.setInputProcessor(inputManager);
renderer = new Renderer(gameManager,orthoHeight, orthoWidth);

Do metody render() přidáme dvě metody pro obsluhu instancí, výsledný její tvar bude:

@Override
public void render(float delta) {
gameManager.update(delta);
renderer.render(delta);
}

Přidáme importy a uložíme.

Rekapitulovat výsledný tvar třídy GameScreen.java po výše uvedených drobných úpravách není nutné, pokud byste si nebyli jisti, naleznete zdrojový kód této a všech ostatních tříd v příloze ke stažení.

Výsledkem předchozího a dnešního dílu je téměř celá objektová kostra. Aplikaci vyzkoušejte, zobrazovaný žlutý obdélník by se měl postupně přesunout na místo vašeho kliku na obrazovce. Projekt obsahuje warnings o nevyužitých proměnných, tyto jistě využijeme v dalších dílech našeho semináře.

Příště vložíme obrázek slepice do naší Android hry v Javě

Příště žlutý obdélník nahradíme grafikou slepice a přidáme další vychytávky.


 

Stáhnout

Staženo 4x (5.78 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í!


 



 

 

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