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

11. diel - Šibenice pre Android - MainGameActivity

V minulej lekcii, Šibenice pre Android - Aktivity a implementácia , sme vytvorili jednotlivé aktivity hry šibenice a implementovali sme menu s výberom okruhov. V dnešnom tutoriále sa budeme venovať hlavná aktivite - MainGameActivity.

Atribúty

Ako prvý si pridáme inštančný premenné, potrebné pre chod hry:

private String slovo = "";
private int chyba = 0;

private int delkaSlova = 0;
private int pocetVyskytu = 0;
private String pomDelka = "";

private int score = 10000;
private int multiplikator = 0;
private String suhadnute = "";
private String zapocitaneChyby = "";

int okruh = 0;

OnCreate ()

Pridajme metódu onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_game);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
    //zakázání změn orientace

    AnimationDrawable animace = new AnimationDrawable();
    ImageView napis = findViewById(R.id.imageView4);

    animace.addFrame(getResources().getDrawable(R.drawable.napis1), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis2), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis3), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis4), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis5), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis6), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis7), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis8), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis9), 1000);
    animace.addFrame(getResources().getDrawable(R.drawable.napis10), 1000);

    napis.setBackgroundDrawable(animace);

    animace.start();

    okruh = getIntent().getIntExtra("VybranaMetoda", 1);

    vyberSlovo();
    uprav(slovo);
}

Tu sa vytvorí objekt AnimationDrawable (animace) a inicializuje sa ImageView (napis). Ďalej sa použije metóda addFrame(), pomocou ktorej do animácie pridáme jednotlivé zábery a nastavíme čas v ms, po ktorý sa bude daný snímka zobrazovať. Objektu napis (ImageView) nastavíme BackgroundDrawable. Parametrom je animace. Potom animáciu spustí a metódou getIntent().getIntExtra() načíta hodnotu položky "VybranaMetoda", defaultná hodnota je 1. Na konci sa volá metóda vyberSlovo() a uprav().

VyberSlovo ()

Metóda vyberSlovo() vytvorí pole String ov. Na základe vybraného okruhu sa do neho uloží slova. Vytvorí objekt Random (ranInfo) a pomocou metódy nextInt() určí náhodné číslo od 0 do dĺžky poľa -1. Do inštančný premenné slovo sa uloží vybrané slovo.

private void vyberSlovo() {
    String[] poleInfo = new String[100];
    int delkaInfo = 0;

    if (okruh == 1) {
        poleInfo = new String[]{"síť", "crack", "hacker", "firewall", "databáze", "počítač", "notebook", "klávesnice", "myš", "ram", "procesor", "java", "android", "windows", "linux", "ubuntu", "lubuntu", "algoritmus", "program", "bios", "hardware", "software", "monitor", "lan", "man", "wan", "ethernet", "proxy", "server", "chrome", "opera", "safari", "komprese", "dekomprese", "informace", "diagram", "kódování", "zdroj", "patice", "frekvence", "sektor", "odezva", "kontrast", "jas", "rozlišení", "skener", "tablet", "projektor", "cyklus", "podmínka", "pascal", "apple", "mac", "procedura"};
    }
    if (okruh == 2) {
        poleInfo = new String[]{"praha", "brno", "ostrava", "plzeň", "liberec", "olomouc", "pardubice", "havířov", "zlín", "kladno", "most", "karviná", "opava", "bruntál", "jihlava", "teplice", "kolín", "šumperk", "chomutov", "přerov", "prostějov", "třebíč", "tábor", "třinec", "znojmo", "příbram", "cheb", "orlová", "trutnov", "písek", "vsetín", "hodonín", "sokolov", "bohumín", "beroun", "jičín", "benešov"};
    }
    if (okruh == 3) {
        poleInfo = new String[]{"klokan", "opice", "zebra", "lama", "slon", "hroch", "velbloud", "nosorožec", "bažant", "medvěd", "slepice", "morče", "ovce", "prase", "koza", "kráva", "kohout", "králík", "zajíc", "tygr", "vlk", "veverka", "žába", "tuleň", "ježek", "fredka", "křeček"};
    }
    if (okruh == 4) {
        poleInfo = new String[]{"audi", "bmw", "citroen", "dacia", "fiat", "ferrari", "kia", "honda", "škoda", "hyundai", "chevrolet", "jaguar", "jeep", "mazda", "mercedes", "mitsubishi", "nissan", "opel", "peugeot", "porsche", "renault", "rover", "saab", "seat", "subaru", "suzuki", "toyota", "volkswagen", "volvo", "bentley", "bugatti", "cadillac", "lada", "dodge", "infinity", "lancia", "lexus", "maybach", "pagani", "proton", "tatra", "trabant", "volha", "zastava"};
    }
    delkaInfo = poleInfo.length;
    Random ranInfo = new Random();
    int losInfo = ranInfo.nextInt(delkaInfo - 1);
    slovo = poleInfo[losInfo];
}

Uprav ()

Dostávame sa k metóde uprav(). Tá vytvorí referencie na objekty TextView od 3 do 10, pretože najkratšia slová budú mať 2 znaky a najdlhšia 10 znakov. Na základe dĺžky slová pomocou GONE "zruší" určitý počet TextView. Parametrom je slovo, ktoré bolo vylosovaných k hádanie:

private void uprav(String hadaneSlovo) {
    TextView[] pismena = new TextView[10];
    pismena[0] = findViewById(R.id.tvp1);
    pismena[1] = findViewById(R.id.tvp2);
    pismena[2] = findViewById(R.id.tvp3);
    pismena[3] = findViewById(R.id.tvp4);
    pismena[4] = findViewById(R.id.tvp5);
    pismena[5] = findViewById(R.id.tvp6);
    pismena[6] = findViewById(R.id.tvp7);
    pismena[7] = findViewById(R.id.tvp8);
    pismena[8] = findViewById(R.id.tvp9);
    pismena[9] = findViewById(R.id.tvp10);

    int vel = hadaneSlovo.length();

    for (int i = vel; i < 10; i++) {
        pismena[i].setVisibility(View.GONE);
    }
}

Vloženom ()

Začnime realizovať vloženie písmená:

public void vlozeni(View v) {
    EditText edte = findViewById(R.id.zadani);
    String zadani = edte.getText().toString().toLowerCase();
    if (zadani.length() >= 1) {
        char zadaneP = zadani.charAt(0);
        edte.setText("");
        if ((zadaneP >= 97 && zadaneP <= 122) || (zadaneP == 283) || (zadaneP == 353) || (zadaneP == 357) || (zadaneP == 269) || (zadaneP == 345) || (zadaneP == 382) || (zadaneP == 253) || (zadaneP == 225) || (zadaneP == 237) || (zadaneP == 233) || (zadaneP == 367) || (zadaneP == 250) || (zadaneP == 243)) {

            for (int i = 0; i < slovo.length(); i++) {
                if (slovo.charAt(i) == zadaneP) {
                    pocetVyskytu++;
                    zapisSpravne(zadaneP, i);
                    scorePlus(zadaneP);
                }
            }

            if (pomDelka.indexOf(zadaneP) == -1) {
                delkaSlova += pocetVyskytu;
                pomDelka += zadaneP;
            }

            if (delkaSlova == slovo.length()) {
                Vyhra();
            }
            if (pocetVyskytu == 0) {
                zapisSpatne(zadaneP);
                scoreMinus(zadaneP);
            }
        } else {
            Toast.makeText(getApplicationContext(), "Není zadáno správné písmeno", Toast.LENGTH_LONG).show();
        }
    }

    pocetVyskytu = 0;
}

Podmienka vyhodnocuje, či sa zadané písmenko vyskytuje v abecede, popr. či to je český znak. (Ľ, š, č atď.). Cyklus for porovná všetky písmená v hádanie slove sa zadaným písmenom (zadaneP). Pokiaľ dôjde k zhode, pripočíta 1 k pocetVyskytu a zavolá metódy zapisSpravne() a scorePlus().

Po každom dokončenom cykle sa pripočíta hodnota pocetVyskytu k hodnote delkaSlova. Atribút delkaSlova použijeme ku kontrole, či sme už uhádli všetky písmená. Tiež nesmieme zabudnúť pridať zadaný znak (zadaneP) do premennej pomDelka. Tým zabezpečíme, že nepričítajú počet uhádnutých písmen viackrát ako raz.

Po zdvihnutí hodnoty pomDelka kontrolujeme podmienkou, či sme už dosiahli dĺžky hádaného slová. Ak áno, hru sme vyhrali a voláme metódu vyhra(). Ak je pocetVyskytu rovný nule, znamená to, že sa zadané písmeno v hádanie slove nevyskytuje. Preto voláme metódy zapisSpatne() a scoreMinus(). Na konci musíme vždy vynulovať "počítadlo zhôd" pocetVyskytu. Pomocou parametra View v sa metóda stane viditeľná, aby sme ju nastavili ako metódu onClick() v XML.

ZapisSpravne ()

Pridávame metódu pre zapísanie uhádnutého písmená do slova. Prepíšeme určité TextView z pôvodného _ na zadané písmeno. Prametry sú zadané písmeno a pozície písmená v slove.

private void zapisSpravne(char pismeno, int pozice) {
    TextView[] pismena = new TextView[10];
    pismena[0] = findViewById(R.id.tvp1);
    pismena[1] = findViewById(R.id.tvp2);
    pismena[2] = findViewById(R.id.tvp3);
    pismena[3] = findViewById(R.id.tvp4);
    pismena[4] = findViewById(R.id.tvp5);
    pismena[5] = findViewById(R.id.tvp6);
    pismena[6] = findViewById(R.id.tvp7);
    pismena[7] = findViewById(R.id.tvp8);
    pismena[8] = findViewById(R.id.tvp9);
    pismena[9] = findViewById(R.id.tvp10);

    pismena[pozice].setText(String.valueOf(pismeno));

}

ZapisSpatne ()

Podobne obslúžime aj zadanie zlého písmená:

private void zapisSpatne(char pismeno) {
    ImageView plocha = findViewById(R.id.zaverecnaPlocha);
    TextView spatne = findViewById(R.id.Chyby);

    String chyby = spatne.getText().toString();

    if (chyby.indexOf(pismeno) == -1) {
        chyba++;
        spatne.append(String.valueOf(pismeno));

        if (chyba == 1) {
            plocha.setImageResource(R.drawable.krok2m);
        } else if (chyba == 2) {
            plocha.setImageResource(R.drawable.krok3m);
        } else if (chyba == 3) {
            plocha.setImageResource(R.drawable.krok4m);
        } else if (chyba == 4) {
            plocha.setImageResource(R.drawable.krok5m);
        } else if (chyba == 5) {
            plocha.setImageResource(R.drawable.krok6m);
        } else if (chyba == 6) {
            plocha.setImageResource(R.drawable.krok7m);
        } else if (chyba == 7) {
            plocha.setImageResource(R.drawable.krok8m);
        } else if (chyba == 8) {
            plocha.setImageResource(R.drawable.krok9m);
        } else if (chyba == 9) {
            konecHry();
        }

    }
}

Do stringu chyby načítame obsah TextView, kam vypisujeme chybná písmená. Ak v reťazci chybné písmeno (parameter) ešte nie je, zdvihneme hodnotu Premeny chyba o 1 a chybné písmeno pridáme do TextView. Na základe hodnoty chyba sa zobrazí správny obrázok s tým, že pokiaľ dôjde k deviatej chybe, voláme metódu konecHry(). Parametrom je chybné písmeno, to preto, že ho budeme pripisovať do TextView, aby hráč mal prehľad, ktorá písmená už hádal.

ScorePlus ()

Metódu scorePlus() voláme v prípade, že hráč písmeno uhádol. Parametrom je uhádnuté písmeno. To kvôli tomu, že ho pridáme do pomocného reťazca suhadnute, aby sme skóre za uhádnuté písmeno pripísali iba prvýkrát. Musíme totiž ošetriť prípad, keď hráč zadá niekoľkokrát za sebou rovnaké písmeno:

private void scorePlus(char pismeno) {
    if (suhadnute.indexOf(pismeno) == -1) {
        MediaPlayer mp = MediaPlayer.create(this, R.raw.sucpis);
        mp.start();
        suhadnute += pismeno;
        multiplikator++;
        score += (500 * multiplikator);
    }
}

Ak je podmienka splnená, vytvorí sa objekt MediaPlayer mp, ktorý berie zdrojové súbory (v tomto prípade .mp3) z priečinka raw/, ktorá sa nachádza v resources. Hneď po vytvorení sa raz prehrá, do reťazca sa pridá uhádnuté písmeno, zdvihne sa multiplikátor a vypočíta sa skóre.

ScoreMinus ()

scoreMinus() voláme v prípade, že hráč písmeno neuhádol. Je to obdobná funkcia ako scorePlus(). Jediné, čo sa mení, je to, že od skóre odčítame 1000 a multiplikátor nastavíme na 0:

private void scoreMinus(char pismeno) {
    if (zapocitaneChyby.indexOf(pismeno) == -1) {
        MediaPlayer mp = MediaPlayer.create(this, R.raw.failpis);
        mp.start();
        zapocitaneChyby += pismeno;
        score -= 1000;
        multiplikator = 0;
    }
}

KonecHry () a vyhra ()

konecHry() voláme v prípade, že hráč prehral a vyhra() v prípade, že hráč hru vyhral. Pomocou Intent preskočíme do aktivity EndGameActivity. Ako extra dáta si vezmeme hodnotu skóre, hádanie slovo a informáciu o tom či hráč prehral alebo vyhral:

private void konecHry() {
    Intent endGame = new Intent(this, EndGameActivity.class);
    endGame.putExtra("VYHRA_PROHRA", 0);
    endGame.putExtra("ID_PROMENNE", score);
    endGame.putExtra("SLOVO", slovo);
    startActivity(endGame);
    finish();
}

private void vyhra() {
    Intent endGame = new Intent(this, EndGameActivity.class);
    endGame.putExtra("VYHRA_PROHRA", 1);
    endGame.putExtra("ID_PROMENNE", score);
    endGame.putExtra("SLOVO", slovo);
    startActivity(endGame);
    finish();
}

Kódovanie charu

Ak niekomu stále nie je jasné, prečo sa v metóde vlozeni() objavila určité čísla v podmienke, odporúčam sa pozorne pozrieť na nasledujúcu snímku.

Kódovanie UTF-16 v Jave - Programovanie Android aplikácií v Jave

Obrázok 8 - príklad kódovanie UTF-16

Môžete sa pozrieť aj na UTF-16 ASCII tabuľku.

Nabudúce, v lekcii Šibenice pre Android - Dokončenie , hru dokončíme pridaním aktivít pre koniec hry a zobrazenie skóre.


 

Predchádzajúci článok
Šibenice pre Android - Aktivity a implementácia
Všetky články v sekcii
Programovanie Android aplikácií v Jave
Preskočiť článok
(neodporúčame)
Šibenice pre Android - Dokončenie
Článok pre vás napísal Jiří Frank
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje programování v C# a vývoji aplikací pro platformu Android a dalším věcem spojeným s Android OS
Aktivity