IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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

V minulé lekci kurzu o programování hry pro Android v Javě, Programujeme Android hru - Rozdělení hry do tříd I, jsme 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ě - Programujeme Android hru

Příště, Programujeme Android hru - Assets load, žlutý obdélník nahradíme grafikou slepice a přidáme další vychytávky.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

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

 

Předchozí článek
Programujeme Android hru - Rozdělení hry do tříd I
Všechny články v sekci
Programujeme Android hru
Přeskočit článek
(nedoporučujeme)
Programujeme Android hru - Assets load
Článek pro vás napsal Jaroslav Polívka
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
Autor se věnuje převážně jazykům JAVA a C++
Aktivity