Vianoce v ITnetwork sú tu! Dobí si teraz kredity a získaj až 80 % extra kreditov na e-learningové kurzy ZADARMO. Zisti viac.
Hľadáme nové posily do ITnetwork tímu. Pozri sa na voľné pozície a pridaj sa k najagilnejšej firme na trhu - Viac informácií.

12. diel - Programujeme Android hru - Kŕmenie I

Vitajte v ďalšom diele nášho kurzu. Z minulého dielu máme našej hru v stave, kedy ide sliepky na miesto kliknutia. Dnes začneme s obsluhou a premietaním krmivá, ktorým budeme našej hlúpu sliepku kŕmiť. Budeme k tomu potrebovať dve triedy. Podľa jednej sa nám vytvorí inštancia nášho kŕmenie. Druhá nám zistí, kde je práve voľné miesto pre umiestnenie onoho kŕmenie, teda tam, kde práve nestojí naše hlúpe kurča.

Začneme druhú zmienenú triedou. V balíčku com.wackychic­ken.managers si vytvoríme novú triedu PosFinder.java a vyplníme ju do nasledujúceho tvaru:

package com.wackychicken.managers;

import java.util.Random;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.wackychicken.screens.GameScreen;

public class PosFinder {

    private final Vector2 demandedScreen,screenBoundBegin,screenBoundEnd;
    private final int beginConstant; //zacatek travy
    private Random random;
    private float coefficient;
    public Rectangle area[];
    private Rectangle receivedRectangle;
    private float [] generatedPosition;
    private float width,height;

    public PosFinder(GameScreen gameScreen,final int beginConstant,Rectangle receivedRectangle,float width,float height) {
        this.demandedScreen=gameScreen.DEMANDED_SCREEN;
        this.screenBoundBegin=gameScreen.SCREEN_BOUND_BEGIN;
        this.screenBoundEnd=gameScreen.SCREEN_BOUND_END;
        this.beginConstant=beginConstant;
        this.coefficient=1.25f;
        this.width=width;
        this.height=height;
        this.random = new Random();

        this.area=new Rectangle[4];
        for(int i=0;i<area.length;i++)
            area[i]=new Rectangle();

        this.receivedRectangle=receivedRectangle; //chickenPositionX,chickenPositionY,chickenWidth,chickenHeight
        this.generatedPosition=new float[2];
    }

    public float [] findOutFreePosition(float positionX,float positionY) {
        receivedRectangle.setPosition(positionX, positionY);
        if( !((receivedRectangle.getY() - screenBoundBegin.y<=beginConstant + height*coefficient)&&//nepravda podminka a i c
(receivedRectangle.getX() - screenBoundBegin.x <=  width*coefficient)) &&
!((screenBoundEnd.y - receivedRectangle.getY()-receivedRectangle.getHeight() <= height*coefficient)&& //nepravda podminka b i c
(receivedRectangle.getX() - screenBoundBegin.x <=  width*coefficient)) &&
!((receivedRectangle.getY() - screenBoundBegin.y<=beginConstant + height*coefficient)&&//nepravda podminka a i d
(screenBoundEnd.x - receivedRectangle.getX() -receivedRectangle.getWidth() <=  width*coefficient)) &&
!((screenBoundEnd.y - receivedRectangle.getY()-receivedRectangle.getHeight() <= height*coefficient)&& //nepravda podminka b i d
(screenBoundEnd.x - receivedRectangle.getX() -receivedRectangle.getWidth() <=  width*coefficient))      )
        {
            if(receivedRectangle.getY() - screenBoundBegin.y<=beginConstant + height*coefficient ) //podminka a
            generatePosition('a');

            else if(screenBoundEnd.y - receivedRectangle.getY()-receivedRectangle.getHeight() <= height*coefficient)//podminka b
                generatePosition('b');
            else if(receivedRectangle.getX() - screenBoundBegin.x <=  width*coefficient)
                generatePosition('c');
            else if(screenBoundEnd.x - receivedRectangle.getX() -receivedRectangle.getWidth() <=  width*coefficient)
                generatePosition('d');
            else
                generatePosition('e');
        }

        else if((receivedRectangle.getY() - screenBoundBegin.y<=beginConstant + height*coefficient)&& //podminka a i C
    (receivedRectangle.getX() - screenBoundBegin.x <=  width*coefficient) )
            generatePosition('f');

        else if((screenBoundEnd.y - receivedRectangle.getY()-receivedRectangle.getHeight() <= height*coefficient)&& //podminka b i C
    (receivedRectangle.getX() - screenBoundBegin.x <=  width*coefficient))
            generatePosition('g');

        else if((receivedRectangle.getY() - screenBoundBegin.y<=beginConstant + height*coefficient)&&   //podminka a i d
    (screenBoundEnd.x - receivedRectangle.getX() -receivedRectangle.getWidth() <=  width*coefficient))
            generatePosition('h');

        else if((screenBoundEnd.y - receivedRectangle.getY()-receivedRectangle.getHeight() <= height*coefficient)&& //podminka b i d
    (screenBoundEnd.x - receivedRectangle.getX() -receivedRectangle.getWidth() <=  width*coefficient))
            generatePosition('i');

        return generatedPosition;
    }

    private void generatePosition(char chickenPlacement) {
        if(chickenPlacement =='a')
        {   //zde je drobna uprava,kdyz je kure moc nahore vzdalenost > (ch.height*0.5) od scrBgn+bgnCnst
            //pak vyber vzdy nejvetsi oblast O
        area[1].set(screenBoundBegin.x,screenBoundBegin.y+beginConstant-height,(receivedRectangle.getX()-screenBoundBegin.x),
(receivedRectangle.getY()+receivedRectangle.getHeight())-(screenBoundBegin.y+beginConstant-height));

        area[0].set(screenBoundBegin.x,(receivedRectangle.getY()+receivedRectangle.getHeight()),
demandedScreen.x,screenBoundEnd.y-(receivedRectangle.getY()+receivedRectangle.getHeight()) );

        area[2].set(receivedRectangle.getX()+receivedRectangle.getWidth(),screenBoundBegin.y+beginConstant-height,
screenBoundEnd.x-receivedRectangle.getX()-receivedRectangle.getWidth(),
receivedRectangle.getY()+receivedRectangle.getHeight()-(screenBoundBegin.y+beginConstant-height));

        area[3].set(0,0,0,0);

        if(receivedRectangle.getY()+receivedRectangle.getHeight()-(screenBoundBegin.y+beginConstant)
< receivedRectangle.getHeight()*0.5f) //kdyz je kure moc nahore vyber nejvetsi oblast
{
            setCoordinate(1);
        }

        else
            setCoordinate(3);
            //Gdx.app.log("posFinder:", "podminka a");
        }

        else if(chickenPlacement =='b') {

            area[0].set(screenBoundBegin.x,screenBoundBegin.y+beginConstant,
            demandedScreen.x,receivedRectangle.getY()-(screenBoundBegin.y+beginConstant));

            area[1].set(screenBoundBegin.x,receivedRectangle.getY(),
receivedRectangle.getX()-screenBoundBegin.x,screenBoundEnd.y-receivedRectangle.getY());

            area[2].set(receivedRectangle.getX()+receivedRectangle.getWidth(),receivedRectangle.getY(),
screenBoundEnd.x-(receivedRectangle.getX()+receivedRectangle.getWidth()),screenBoundEnd.y-receivedRectangle.getY());

            area[3].set(0,0,0,0);
            setCoordinate(3);
            //Gdx.app.log("posFinder:", "podminka b");
        }

        else if(chickenPlacement =='c')
        {
            area[0].set(screenBoundBegin.x,screenBoundBegin.y+beginConstant,
            demandedScreen.x,receivedRectangle.getY()-(screenBoundBegin.y+beginConstant));

            area[1].set(receivedRectangle.getX()+receivedRectangle.getWidth(),receivedRectangle.getY(),
screenBoundEnd.x-(receivedRectangle.getX()+receivedRectangle.getWidth()),receivedRectangle.getHeight());

            area[2].set(screenBoundBegin.x,receivedRectangle.getY()+receivedRectangle.getHeight(),
demandedScreen.x,screenBoundEnd.y-(receivedRectangle.getY()+receivedRectangle.getHeight()));

            area[3].set(0,0,0,0);
            setCoordinate(3);
            //Gdx.app.log("posFinder:", "podminka c");
        }

        else if(chickenPlacement =='d')
        {
            area[0].set(screenBoundBegin.x,screenBoundBegin.y+beginConstant,
demandedScreen.x,receivedRectangle.getY()-(screenBoundBegin.y+beginConstant));

            area[1].set(screenBoundBegin.x,receivedRectangle.getY(),
receivedRectangle.getX()-screenBoundBegin.x,receivedRectangle.getHeight());

            area[2].set(screenBoundBegin.x,receivedRectangle.getY()+receivedRectangle.getHeight(),
demandedScreen.x,screenBoundEnd.y-(receivedRectangle.getY()+receivedRectangle.getHeight()));

            area[3].set(0,0,0,0);

            setCoordinate(3);
            //Gdx.app.log("posFinder:", "podminka d");
        }

        else if(chickenPlacement =='e')
        {
            area[0].set(screenBoundBegin.x,screenBoundBegin.y+beginConstant,
            demandedScreen.x,receivedRectangle.getY()-(screenBoundBegin.y+beginConstant));

            area[1].set(screenBoundBegin.x,receivedRectangle.getY(),
            receivedRectangle.getX()-screenBoundBegin.x,receivedRectangle.getHeight());

                area[2].set(receivedRectangle.getX()+receivedRectangle.getWidth(),receivedRectangle.getY(),
screenBoundEnd.x-(receivedRectangle.getX()+receivedRectangle.getWidth()),receivedRectangle.getHeight());

            area[3].set(screenBoundBegin.x,receivedRectangle.getY()+receivedRectangle.getHeight(),
demandedScreen.x,screenBoundEnd.y-(receivedRectangle.getY()+receivedRectangle.getHeight()));

            setCoordinate(4);
            //Gdx.app.log("posFinder:", "ostatni prostor");
        }


        else if(chickenPlacement =='f')
        {
            area[0].set(receivedRectangle.getX()+receivedRectangle.getWidth(),screenBoundBegin.y+beginConstant-height,
(screenBoundEnd.x-(receivedRectangle.getX()+receivedRectangle.getWidth()) ),
((receivedRectangle.getY()+receivedRectangle.getHeight())-(screenBoundBegin.y+beginConstant-height)));

            area[1].set(screenBoundBegin.x,receivedRectangle.getY()+receivedRectangle.getHeight(),
demandedScreen.x,screenBoundEnd.y-(receivedRectangle.getY()+receivedRectangle.getHeight()));

            area[2].set(0,0,0,0);
            area[3].set(0,0,0,0);

            setCoordinate(2);
            //Gdx.app.log("posFinder:", "podminka a i c");
        }

        else if(chickenPlacement =='g')
        {
                area[0].set(screenBoundBegin.x,screenBoundBegin.y+beginConstant,demandedScreen.x,
receivedRectangle.getY()-(screenBoundBegin.y+beginConstant));

                        area[1].set(receivedRectangle.getX()+receivedRectangle.getWidth(),receivedRectangle.getY(),
screenBoundEnd.x-(receivedRectangle.getX()+receivedRectangle.getWidth()),screenBoundEnd.y-receivedRectangle.getY());

            area[2].set(0,0,0,0);
            area[3].set(0,0,0,0);

            setCoordinate(2);
            //Gdx.app.log("posFinder:", "podminka b i c");
        }

        else if(chickenPlacement =='h')
        {
            area[0].set(screenBoundBegin.x,screenBoundBegin.y+beginConstant-height,receivedRectangle.getX()- screenBoundBegin.x,
((receivedRectangle.getY()+receivedRectangle.getHeight())-(screenBoundBegin.y+beginConstant-height)));

                        area[1].set(screenBoundBegin.x,receivedRectangle.getY()+receivedRectangle.getHeight(),demandedScreen.x,
screenBoundEnd.y-(receivedRectangle.getY()+receivedRectangle.getHeight()));

            area[2].set(0,0,0,0);
            area[3].set(0,0,0,0);

            setCoordinate(2);
            //Gdx.app.log("posFinder:", "podminka a i d");
        }

        else if(chickenPlacement =='i')
        {
            area[0].set(screenBoundBegin.x,screenBoundBegin.y+beginConstant,demandedScreen.x,
receivedRectangle.getY()-(screenBoundBegin.y+beginConstant));

            area[1].set(screenBoundBegin.x,receivedRectangle.getY(),
receivedRectangle.getX()-screenBoundBegin.x,screenBoundEnd.y-receivedRectangle.getY());

            area[2].set(0,0,0,0);
            area[3].set(0,0,0,0);
            setCoordinate(2);
            //Gdx.app.log("posFinder:", "podminka b i d");
        }

    }

    private void setCoordinate(int areasSum) {
        int i = random.nextInt(areasSum);
        int rangeX=(int)(area[i].x+area[i].width-area[i].x-width);  // sychrovka minimum pro random musí být 1
        int rangeY=(int)(area[i].y+area[i].height-area[i].y-height); // sychrovka minimum pro random musí být 1
        if(rangeX<1)
            rangeX=1;
        if(rangeY<1)
            rangeY=1;
        generatedPosition[0] = random.nextInt(rangeX)+area[i].x;
        generatedPosition[1] = random.nextInt(rangeY)+area[i].y;
    }

}

Triedu si uložíme, vypísal som aj importy, takže pridávať ich nemusíme. Obe triedy si vysvetlíme v druhej časti tohto dielu. Poďme ďalej a v balíčku com.wackychic­ken.gameobjec­ts si vytvoríme novú triedu Food.java a prekopíruje do nasledujúceho tvaru:

package com.wackychicken.gameobjects;

import com.badlogic.gdx.math.Rectangle;
import com.wackychicken.managers.PosFinder;
import com.wackychicken.screens.GameScreen;

public class Food {
    private final float WIDTH=32,HEIGHT=32;
    private float positionX,positionY;
    private float lifeTime,newLifeTime,counter;
    private Rectangle rectForOverlap;
    private int mask;

    private Rectangle chickenRectangle;
    private PosFinder posFinder;
    private float []generatedPosition;
    private Chicken chicken;
    public enum Type {WHEAT,CORN,BERRY,CARROT}
    private boolean wasClicked,wasCounted;

    public Food(GameScreen gameScreen,Chicken chicken,final int BEGINYCONSTANT) {
        this.lifeTime=this.newLifeTime=10;
        this.generatedPosition=new float[2];
        this.chicken=chicken;
        this.chickenRectangle=new Rectangle(chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
        this.wasClicked=this.wasCounted=false;
        this.counter=0;
        this.mask=0;

        posFinder=new PosFinder(gameScreen,BEGINYCONSTANT,chickenRectangle,WIDTH,HEIGHT);
        generatedPosition=posFinder.findOutFreePosition(chicken.getPositionX(),chicken.getPositionY());
        this.positionX=generatedPosition[0];
        this.positionY=generatedPosition[1];
        this.rectForOverlap = new Rectangle(positionX,positionY,this.WIDTH,this.HEIGHT);
    }

    public void update(float delta) {
        rectForOverlap.set(positionX, positionY, this.WIDTH, this.HEIGHT);
        if(lifeTime<=0)
        {
            generatedPosition=posFinder.findOutFreePosition(chicken.getPositionX(),chicken.getPositionY());
            positionX=generatedPosition[0];
            positionY=generatedPosition[1];
            wasClicked=wasCounted=false;
            lifeTime=newLifeTime;
            updateMask();
        }
        lifeTime-=delta;
        updateNewLifeTime(delta);
    }

    private void updateNewLifeTime(float delta){ //postupne snizovani pocatecni hodnoty lifeTime foodu z 10 na 5
        if(counter+delta>110)
        {
            newLifeTime-=1;
            if(newLifeTime-delta<4)newLifeTime=4;   //minimalni lifetime foodu je 4
            counter=0;
        }
        else
            counter+=delta;
    }

    public void restart() {
        this.lifeTime=this.newLifeTime=10;
        this.chickenRectangle.set(chicken.getPositionX(),chicken.getPositionY(),chicken.getWidth(),chicken.getHeight());
        this.wasClicked=this.wasCounted=false;
        this.counter=0;
        this.mask=0;
        generatedPosition=posFinder.findOutFreePosition(chicken.getPositionX(),chicken.getPositionY());
        this.positionX=generatedPosition[0];
        this.positionY=generatedPosition[1];
        this.rectForOverlap.set(positionX,positionY,this.WIDTH,this.HEIGHT);
    }

    public PosFinder getPosFinder() {
        return posFinder;
    }

    public float getPositionX() {
        return positionX;
    }

    public float getPositionY() {
        return positionY;
    }

    public float getWidth() {
        return WIDTH;
    }

    public float getHeight() {
        return HEIGHT;
    }

    public float getLifeTime() {
        return lifeTime;
    }

    public void setLifeTime(float time) {
        this.lifeTime=time; //kvuli objectMng - po animaci chtit novou pozici foodu
    }

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

    public Rectangle getRectForOverlap() { //kvuli OverlapsManager
        return rectForOverlap;
    }

    public void setWasClicked(boolean x) { //kvuli OverlapsManager
        wasClicked=x;
    }

    public boolean getWasClicked(){ //kvuli OverlapsManager
        return wasClicked;
    }

    public void setWasCounted(boolean x) { //kvuli OverlapsManager
        wasCounted=x;
    }

    public boolean getWasCounted() { //kvuli OverlapsManager
        return wasCounted;
    }

    public int getMask() {
        return this.mask;
    }

    private void updateMask() {
        mask++;
        if(mask>3)
            mask=0;
    }
}

Triedu si uložíme, opäť som vypísal aj importy, takže nepridávame. Ospravedlňte dnešnej dlhý kód a tým pádom aj strohý diel. Pre dnešok nám naozaj stačí, keď správne prekopíruje obsah tried a umiestnime ich do správnych balíčkov. Princíp si vysvetlíme nabudúce. Motiváciou pre nás môže byť zistenie, že v ďalších dieloch pridáme už len jednu triedu, budeme sa teda blížiť k cieľu.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 18x (16.07 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Programujeme Android hru - Grafika II
Všetky články v sekcii
Programujeme Android hru
Preskočiť článok
(neodporúčame)
Programujeme Android hru - Kŕmenie II
Článok pre vás napísal Jaroslav Polívka
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje převážně jazykům JAVA a C++
Aktivity