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