07. Základná herná logika

Po tom, ako sme absolvovali rýchlokurz programovania vraciame sa k nášmu hernému projektu. Opustili sme ho v stave, že máme na hernom stole náhodne vygenerované prekážky, vieme pomocou stlačenia medzery odpáliť loptičku a keď loptička trafí do cieľovej diery v stole, zahrá víťazná hudba.
Výrazne nám pri tom doteraz pomáhali už hotové skripty, ktoré sme si stiahli a vložili do projektu. Odteraz si už budeme základné skripty písať sami. A začneme nevyhnutným prvkom každej hry: Hernou logikou.
Pokračujte vo svojom projekte, prípadne tu si môžete stiahnuť hotový: MojaHra_06.zip
Pravidlá hry
Doteraz má naša hra len základnú interakciu a vlastne ani nevieme, čo je cieľom a ako sa vyhodnocuje. To je otázka tzv. hernej logiky alebo pravidiel hry. Poďme si ich stručne zadefinovať:
- Cieľom je dopraviť loptičku do otvoru v stole
- Kým hra beží, počíta sa počet úderov aj celkový čas
- Po dopravení loptičky do cieľa hra končí, na obrazovku sa vypíše dosiahnutý počet úderov a celkový čas.
Hlavný skript
Na obsluhovanie hlavnej hernej logiky si vytvoríme skript, ktorý bude držať informácie o počte úderov, o uplynutom čase a neskôr sa postará aj o to, aby hra išla pauznúť alebo po dohratí spustiť znova. Bude to náš hlavný skript.
- Vytvorte nový prázdny game objekt s názvom Hra
- Vytvorte skript s názvom Main a priraďte ho na game objekt Hra
Ak si chceme uchovávať nejakú informáciu – napríklad počet úderov – potrebujeme na to v skripte miesto, kam túto informáciu uložíme a kde ju budeme aktualizovať. Čiže? Vytvoríme si na to nejakú vlastnosť.
Vytvorte v skripte Main vlastnosť s názvom shots. Akého typu bude táto vlastnosť? Akú počiatočnú hodnotu jej dáme?
Počítadlo úderov by sme mali, poďme ho niečím plniť. Niekam by sme teda mali doplniť príkaz, ktorý pri každom údere zvýši počítadlo. Naša hra funguje tak, že po stlačení medzery sa loptička odpáli. Toto robí už hotový skript Player.cs a nebudeme teraz do neho siahať. Ale využijeme to, že funguje na stlačenie medzery.
Doplňte skript Main tak, že pri stlačení medzery sa o 1 zvýši shots a do konzoly sa vypíše hodnota vlastnosti shots.

Ďalej dorobíme počítadlo uplynutého času. Znova v skripte Main.
Doplňte do skriptu Main vlastnosť time, do ktorej si o budeme ukladať čas. Akého typu bude táto vlastnosť?
S časom sme pracovali niekoľko lekcií dozadu, tak si len pripomeňme, že vo vlastnosti Time.deltaTime máme uložené koľko trval predošlý frejm. Ak teda túto hodnotu v každom jednom frejme pripočítame k time, bude sa nám takto v time kumulovať celkový uplynutý čas:
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
shots++;
Debug.Log("Pocet uderov: " + shots);
}
time = time + Time.deltaTime;
}
Po spustení hry môžeme v Inšpektore vidieť, ako rastie čas:

Ak v Inšpektore nevidíte vlastnosť Time, zmeňte v kóde vlastnosť time na public.
Chce to pauzu
Aby sme mohli hru pauznúť, pomôžeme si opäť časom. Okrem vlastnosti Time.deltaTime sme si spomínali aj vlastnosť Time.timeScale, a tú presne teraz využijeme. Je to vlastnosť, ktorá určuje rýchlosť plynutia času. Ak ju nastavíme na 0, tak čas zastane úplne. Ak ju nastavíme na 1 čas bude plynúť normálnou rýchlosťou.
Doplňte skript Main tak, aby sa pri stlačení klávesy Esc zastavil čas a do konzoly sa vypíše „Pauza“.
Keď to vyskúšame v hre, tak naozaj po stlačení Esc sa hodnota času Time v inšpektore prestane meniť. Prestane sa aj kotúľať loptička a prestane sa dať pohybovať po stole. Naďalej sa ale dá otáčať a naďalej s otáčajú aj žltí pajďuláci. To doriešime neskôr. Teda vy to doriešite neskôr 😉 Teraz nám stačí, že sa prestal počítať Time.
Chce to odpauznúť
Na ten istý kláves Esc chceme, aby sa hra aj naspäť odpauzla, t.j. aby sa Time.timeScale nastavila naspäť na 1.
Chceme aby sa na ten istý kláves robili dve rôzne veci: raz aby hra zastala, inokedy aby sa rozbehla. Budeme teda potrebovať vyrobiť vetvenie v programe. Na to už poznáme konštrukciu if ... else ..., ktorá nám umožňuje spýtať sa na nejaký predpoklad a podľa toho či platí alebo neplatí sa vykoná jeden alebo druhý variant.
Za akého predpokladu chceme, aby sa hra odpauzla? Za takého, že hra je pauznutá. Ako vieme, že je hra pauznutá? Vieme to z niečoho vyčítať? Je to práve hodnota Time.timeScale, ktorá keď je 0, tak vieme, že hra je pauznutá.
Upravte skript, aby po stlačení klávesy Esc fungoval takto:
- Ak je
Time.timeScalerovný 1 nastavíTime.timeScalena 0 a vypíše „Pauza“ - Inak nastaví
Time.timeScalenaspäť na 1 a vypíše „Koniec pauzy“
Po tejto úprave by už hra mala ísť stlačením Esc pauznúť aj odpauznúť. Len tie prekliate žlté prekážky sa stále otáčajú bez ohľadu na to, či sme hru pauzli alebo nepauzli.
Domáca úloha
Žlté prekážky sa generujú z prefabu Prekazka. Ich otáčanie vytvára skript Rotator, ktorý je na tomto prefabe. A tento skript má dva nedostatky:
- otáčanie je robené zlým spôsobom, nezohľadňuje dĺžku trvania frejmu
- náhodne vygenerovaná rýchlosť je vždy len celé číslo, takže často sa stane, že vygeneruje 0 a prekážka sa potom neotáča vôbec.
Zmeňte skript Rotator tak, aby otáčanie záviselo aj od času trvania frejmu. To spôsobí, že sa otáčanie zastaví pri zastavení času. Je to to isté, ako sme riešili v programovacej lekcii Čas.
Zmeňte skript Rotator tak, aby namiesto celých čísel generoval náhodné desatinné čísla. Toto sme už raz riešili v programovacej lekcii Náhodnosť.
Hotový projekt po tejto lekcii: MojaHra_07.zip
