Cykly a podmienky
Last updated
Last updated
Vytvorme generátor levelu, ktorý na celú šírku obrazovky vytvorí terén pozostávajúci zo štvorcových dielikov v rôznej výške. Dieliky majú veľkosť d
. Výška terénu je v každom stĺpci náhodná. Spodné dieliky sú hnedé ako hlina, najvyššie dieliky sú zelená ako tráva. Ak má náhodou stĺpec výšku 0, tak sa vykreslí modrý dielik pre vodu.
A náhodne sa nad každým stĺpcom môže vykresliť aj žltá minca.
Zopakujeme si pri tom tieto koncepty:
Cyklus for
Dvojitý cyklus for
Podmienka if
Náhodnosť
Rozdelíme si úlohu na pod-úlohy tak, že najprv napíšeme kód na vykreslenie jedného jediného stĺpca, vyriešime tam ofarbovanie tehličiek podľa výšky. A potom pomocou cyklu nakreslíme stĺpce vedľa seba.
Nebudeme potrebovať žiadnu animáciu ani interakciu, takže nateraz si vystačíme s jednoduchým skečom bez setup
a draw
. Nastavíme si veľkosť okna, farbu pozadia a vyrobíme si premennú, ktorá d
, ktorá bude definovať veľkosť jedného dieliku.
Vytvorme si premennú vyska
, ktorá bude definovať, koľko dielkov je v stĺpci. Zatiaľ si ju nastavme napríklad na hodnotu 4:
A pomocou for
cyklu vykreslíme nad seba dieliky v počte vyska
:
Takýto program vykreslí dieliky odhora:
Musíme sa preto pohrať s y-súradnicou v príkaze square
. Ľavý horný roh prvého dielika chceme mať vo výške height-d
, druhý dielik bude vo výške height-2*d
, tretí dielik vo výške height-3*d
a tak ďalej, takže výraz i*d musíme prepísať takto:
Vyskúšajte rôzne hodnoty premennej vyska, uistite sa, že sa vždy vykreslí správny počet dielikov:
Štandardne chceme všetky dieliky hnedé:
Ale ak chceme, aby posledný dielik v poradí bol zelený, musíme si pomôcť podmienkou. Ak ide o posledný dielik v poradí, nastav farbu na zelenú, inak nastav farbu na hnedú.
Ako vieme, že ide o posledný dielik? Podľa hodnoty i
. A aká je posledná hodnota i
ak cyklus ide od i=0
po i < vyska
? Je to vyska-1
. Podmienku teda napíšeme takto:
Ešte doplníme prípad, ak výška je rovná 0. Vtedy vykreslíme len modrý dielik. Znovu si pomôžeme podmienkou if
. Ak je výška väčšia ako 0, tak sa vykoná tento náš už existujúci cyklus. A inak sa vykreslí modrý dielik:
Nastavte premennú vyska
na 0
a vyskúšajte, či program funguje:
Tým by sme mali jeden stĺpec vyriešený a môžeme začať stĺce vedľa seba opakovať.
V programe už máme jeden cyklus for
, ktorý kreslí dieliky nad seba a vytvára stĺpec. Vytvoríme druhý cyklus for, ktorý bude opakovať stĺpce vedľa seba.
Koľko ale budeme potrebovať stĺpcov? To si vypočítame podľa veľkosti dieliku a veľkosti obrazovky a uložme si to do premennej stlpcov
a zavrieme zvyšok programu o veľkého for
cyklu:
Zatiaľ program viditeľne nič nerobí:
Ale to je preto, že síce nakreslíme veľa stĺpcov, akurát im nijak nemeníme x-súradnicu v príkaze square
, takže všetky sú natlačené vľavo na súradnici 0. Musíme teda nuly nahradiť výrazom, ktorý sa odvíja od stĺpca, v ktorom sme:
Teraz sú všetky stĺpce rovnako vysoké, lebo nijak nemeníme ich výšku. V každo opakovaní veľkého cyklu, ktorý ide cez stĺpce teda musíme určiť náhodnú výšku každému stĺpcu.
Z akého rozsahu bude? Vyrátajme si, koľko najviac riadkov môže terén mať podľa výšky okna a veľkosti dielika:
A nastavme výšku pred každým jedným stĺpcom na náhodnú hodnotu:
Toto je dosť divoký terén, preto upravíme generovanie výšky. Namiesto toho, aby každá výška bola kompletne náhodná, tak zmeníme kód tak, aby sa výška ďalšieho stĺpca líšila od súčasnej výšky maximálne o 1.
Nastavme na začiatku výšku na nejakú peknú hodnotu, napríklad na tretinu maximálneho počtu riadkov:
A teraz namiesto nastavenia úplne náhodnej výšky vnútri cyklu, si nastavíme, aby sa výška zmenila náhodné číslo z rozsahu -1, 0, 1:
Prečo sme použili nejaké neznáme round
namiesto známeho int
? Lebo round
zaokrúhľuje v tomto prípade lepšie ako int
. Koho to zaujíma, môže si rozbaliť vysvetlenie tejto zákernosti, ale koho nie, môže to preskočiť.
Po tejto úprave náhodnosti z úplne divokej na náhodnosť plus mínus jedna už vyzerá terén pekne:
Ak nám vadia dlhé vodné plochy, tak tie vznikajú preto, že vyska
klesne hlboko do záporných čísel a chvíľu jej trvá, kým vylezie naspäť nad nulu. Môžeme tomu pomôcť napríklad tak, že ak klesne vyska
pod 0, vrátime ju na 0. Zabráni to výške, aby klesla príliš hlboko.
Upravený generátor funguje výborne:
Správny level musí obsahovať aj niečo, čo sa dá zbierať. My vygenerujeme nad terénom zlaté mince. Mince sa budú generovať iba nad terénom nie nad vodou. Preto kód na vykreslenie mince vložíme do veľkého cyklu, po vykreslení stĺpca:
A máme mince všade nad terénom:
My ich ale nechceme mať všade. Chceme aby sa minca objavila napríklad iba v jednom prípade z desiatich. Pomôžeme si tak náhodnou podmienkou:
Na koniec ešte otestujeme, či náš generátor funguje dobre pre rôzne hodnoty veľkosti dielika:
vyska=6
d=40