Codemas - 18. den

Záchrana Vánoc zdárně pokračuje. Do Štědrého dne nám zbývá skoro ještě celý týden a naše hra už je téměř hotová! Hó hó hó, řekl by Santa. Jenže my máme Ježíška, který se jen radostně zachichotá a zatleská.

Na hře nám samozřejmě zbývá ještě spousta práce, ale to nejtěžší máme opravdu za sebou. Dnes přidáme zvětšování skóre, když robot chytí dárek, a také doplníme zvuky, aby naše hra byla trochu živější.

Zvětšování skóre

Skóre musíme někde uchovávat, ale to je jednoduché. Už máme objekt hra, takže do něj přidáme další vlastnost skore, kam si budeme aktuální skóre ukládat.

Zároveň si potřebujeme uložit i odkaz na HTML prvek v hlavičce hry, do kterého budeme skóre zapisovat. Prvek má id="pocet" a my už umíme použít document.getElementById pro získání potřebného odkazu.

V souboru skript.js najdi někde na začátku našeho programu objekt hra a přidej vlastnost skore a skoreElement:

// objekt pro hru
let hra = {
  element: document.getElementById('hra'),
  sirka: 900,
  vyska: 600,
  dalsiDarek: 150,
  skore: 0,
  skoreElement: document.getElementById('pocet')
}

Textový obsah HTML prvku

Odkaz na HTML prvek, kam budeme zapisovat skóre, máme uložený v hra.skoreElement. U textových HTML prvků lze JavaScriptem měnit jejich obsah pomocí vlastnosti textContent. Naše skóre tedy budeme zapisovat do hra.skoreElement.textContent.

Přidejme do hry malou funkci zvetsiSkore, které zajistí zvětšení skóre o 1 a jeho vypsání na obrazovku:

// zvětší skóre o 1 a vypíše ho na obrazovku
function zvetsiSkore() {
  // zvětšíme o 1
  hra.skore++;
  // vypíšeme do prvku v hlavičce hry
  hra.skoreElement.textContent = hra.skore;
}

Možná se divíte, co znamená zápis hra.skore++. Operátor ++ je v JavaScriptu zkratka pro zvětšení o 1 a obdobně funguje i -- pro zmenšení o 1. Jde o kratší a "víc cool" zápis než hra.skore = hra.skore + 1.

Nyní máme funkci pro zvětšování skóre, ale musíme ji někde volat. Sebrání dárku testujeme uvnitř funkce otestujDarky. Dovnitř podmínky pro testování protnutí obdélníků robota a dárku doplníme volání naší funkce zvetsiSkore().

Celá funkce otestujDarky bude nyní vypadat takto:

// funkce pro testování padajících dárků

function otestujDarky() {
  // projdeme pozpátku všechny dárky v poli
  for (let i = darky.length - 1; i >=0; i--) {

    if (protnutiObdelniku(robot, darky[i])) {
      // obrázek dárku se protnul s obrázkem robota = robot sebere dárek
      // odstraníme sebraný dárek ze hry
      odstranDarek(i);

      // zvětšíme skóre
      zvetsiSkore();

    } else if (darky[i].y + darky[i].vyska > hra.vyska) {
      // dopadl dárek na zem?
      // odstraníme dárek
      odstranDarek(i);
    }

  }
}

Když hru vyzkoušíme a chytíme robotem nějaké dárky, vidíme, že se nám skóre na obrazovce hezky zvětšuje.

Pojďme teď hru trochu oživit a přidat do ní zvuky.

Zvuky

Každá správná hra obsahuje zvuky. Nebudeme to s nimi přehánět, ale měli bychom mít alespoň dva nebo tři. Určitě zvuk při sebrání dárku, zvuk při pádu dárku na zem a možná nějakou hezkou hudbu na pozadí.

Stáhni si prosím balíček zvuků a rozbal si ho u sebe na disku. V balíčku je složka zvuky, ve které je hudba a dva další audio soubory.

Celou složku zvuky vezmi a přetáhni do levého pruhu editoru Repl.it, kde jsou soubory našeho projektu. Zvuky (včetně složky) by se měly nahrát do tvého projektu:


Codemas Zvuky

V HTML existuje značka <audio>, kterou můžeme přidat zvukové soubory do webové stránky. Značka má několik atributů, nás zajímají hlavně tyto:

  • src="zvuk.mp3", kam se jako hodnota uvádí cesta k souboru se zvukem.
  • preload="auto", aby prohlížeč zvuk načetl dopředu i ve chvíli, kdy ještě nehraje.
  • loop, který se uvede, chceme-li, aby se zvuk opakoval stále dokola. To použijeme pro naši hudbu.

Otevřeme index.html a někam na konec stránky, ale před značku <script>, kterou připojujeme do stránky náš skript.js, vložíme následující kód:

<audio id="hudba" src="zvuky/hudba.mp3" preload="auto" loop></audio>
<audio id="zvuk-naraz" src="zvuky/naraz.mp3" preload="auto"></audio>
<audio id="zvuk-sebrano" src="zvuky/sebrano.mp3" preload="auto"></audio>

V HTML máme zvuky přidané. Všimni si, že jsme všem zvukům přidali atribut id, takže už asi tušíš, co bude následovat. Ano, musíme si na zvuky v JavaScriptu vytvořit odkazy, abychom je mohli ovládat.

Odkazy na zvuky si uložíme opět do vlastnosti objektu hra (přidáme poslední 3 řádky uvnitř objektu):

// objekt pro hru
let hra = {
  element: document.getElementById('hra'),
  sirka: 900,
  vyska: 600,
  dalsiDarek: 150,
  skore: 0,
  skoreElement: document.getElementById('pocet'),
  hudba: document.getElementById('hudba'),
  zvukNaraz: document.getElementById('naraz'),
  zvukSebrano: document.getElementById('sebrano')
}

Audio prvky se v JavaScriptu ovládají celkem jednoduše. Stačí zavolat odkazNaZvuk.play() a je to! Kdybychom chtěli naopak zvuk zastavit (např. hudbu), stačí zavolat metodu pause().

Při startu hry chceme spustit hudbu. Do funkce startHry přidej:

// spustíme hudbu
hra.hudba.play();

Druhé dva zvuky budeme spouštět ve chvíli, když robot sebere dárek nebo když dárek dopadne na zem. Přehrání příslušných zvuků doplníme do podmínek uvnitř funkce otestujDarky. Celá funkce otestujDarky bude vypadat takto (přidali jsme řádky 17 a 25):

// funkce pro testování padajících dárků
// - dopadl dárek na zem?
// - chytil dárek robot?
function otestujDarky() {
  // projdeme pozpátku všechny dárky v poli
  for (let i = darky.length - 1; i >=0; i--) {

    if (protnutiObdelniku(robot, darky[i])) {
      // obrázek dárku se protnul s obrázkem robota = robot sebere dárek
      // odstraníme sebraný dárek ze hry
      odstranDarek(i);

      // zvětšíme skóre
      zvetsiSkore();

      // přehraj zvuk sebraného dárku
      hra.zvukSebrano.play();

    } else if (darky[i].y + darky[i].vyska > hra.vyska) {
      // dopadl dárek na zem?
      // odstraníme dárek
      odstranDarek(i);

      // přehraj zvuk nárazu na zem
      hra.zvukNaraz.play();
    }

  }
}

Zvuky nehrají?

Je možné, že se vám zvuky nepřehrávají, i když jste udělali všechno správně. Moderní prohlížeče se totiž snaží zabránit tomu, aby webové stránky začali samy od sebe hrát a obtěžovaly tak uživatele, takže zvuky zakazují. Je možné, že ve tvém prohlížeči budou fungovat zvuky sebrání dárku a dopadu na zem (asi funguje ve Firefoxu), nebo se nepřehrává nic (asi v Chrome).

Řešení je celkem jednoduché - prohlížeče povolí zvuky ve chvíli, kdy uživatel například klikne na tlačítko. Já vím, že už jste se těšili, že naše hra začne zvučet, ale toto vyřešíme až zítra.

V naší hře máme zvuky připravené, zítra přidáme do hry startovní obrazovku, na které bude tlačítko START, které hru odstartuje. Protože stisk tohoto tlačítka bude zároveň interakce, kterou prohlížeč potřebuje k tomu, aby prohlížeč povolil zvuky, vše začne krásně fungovat.

Na závěr

Jak už se v programování stává, opět jsme se dostali do situace, kdy jsme napsali kód, který zatím nemůžeme vyzkoušet, dokud zítra nenapíšeme kód další. Nevěšte hlavu a běžte si mlsnout trochu vánočního cukroví, určitě už máte nějaké napečené. Zlepšení nálady je zaručeno :) Zítra vše doženeme.

Pro případ, že se ti dnes něco nepovedlo, kompletní kód hry po dnešních úpravách si můžeš prohlédnout zde.

Máš-li dotazy, diskutuj u příspěvku pro dnešní den ve facebookové události. Těšíme se na tebe opět zítra.