Zůstaň doma a naprogramuj si hru 11

Vítám tě u posledního dílu této challenge. Zbývají nám 2 poslední věci k dokončení hry, časomíra a ukončení hry.

Začneme časomírou. Podobným způsobem jako včera si musíme propojit JavaScript s elementem, který vypisuje časomíru. Vytvořme si novou proměnnou s názvem timeElement a propojme si ho s elementem, který má ID time.

let timeElement= document.getElementById("time");

Bude se nám také pro nastavení časomíry hodit další proměnná, nazveme si ji jako time.

let time = 0;

Proměnnou využijeme ve funkci startGame, kde jí nastavíme hodnotu (na jednu minutu) a později zavoláme funkci, která obsluhuje časomíru.

function startGame() {
    time = 60;
    createPills();
    draw();
}

Na samotnou časomíru si vytvoříme samostatnou funkci s názvem timer. Protože chceme, aby nám časovač běžel souběžně se hrou, vytvoříme si v ní další funkci s názvem startTimer, kterou zavoláme na konci funkce timer.

function timer() {
    function startTimer(duration, display) {
        
    }
  
    startTimer(time, game.timeElement);
}

Ve funkci startTimer si vytvoříme 3 proměnné – timer, minutes a seconds. Do proměnné timer uložíme náš zvolený čas time a do ostatních výchozí hodnotu 0.

function timer() {
    function startTimer() {
        let timer = time;
        let minutes = 0;
        let seconds = 0;        
    }
  
    startTimer();
}

Vytvoříme si další proměnnou s názvem countDownInterval. Do této proměnné uložíme funkci setInterval, která se postará o odpočet.

let countDownInterval = setInterval(function () {
    minutes = parseInt(timer / 60, 10);
    seconds = parseInt(timer % 60, 10);

    minutes = minutes < 10 ? "0" + minutes : minutes;
    seconds = seconds < 10 ? "0" + seconds : seconds;

    timeElement.textContent = minutes + ":" + seconds;         
    timer--;
}, 1000);

Do funkce setInterval si umístíme ještě jednu funkci bez jména, která převádí hodnotu v proměnné timer na minuty a sekundy. Následně vidíme ve funkci tyto dva řádky kódu:

minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;

Výraz, který se nachází za "=" je tzv. jednořádková podmínka. V určitých případech nepotřebujeme psát podmínku v jejím úplném tvaru, ale vytvoříme kratší zápis. Před otazníkem se nachází logický výraz. Pokud bude pravdivý, dosadí se do proměnné ta část, která je za otazníkem a zároveň před dvojtečkou, za dvojtečkou je potom hodnota, která se do proměnné dosadí, pokud je výraz nepravdivý. Tyto dva řádky kódu jsme tam vložili proto, aby měl čas jednotný formát, tzn. nebude se nám zobrazovat 1:33 nebo 0:5, ale 01:33 a 00:05.

Na konci funkce je potom naše dobrá známá funkce textContent, která upravuje obsah elementu a odečítání hodnoty od proměnné timer (tzn. dekrement, odečítáme 1 od hodnoty).

Za složenou závorkou si můžeš všimnout čárky a čísla 1000. To nám ukazuje délku jednoho intervalu a udává se v milisekundách, proto 1000 = 1s.

Funkce timer by měla vypadat následovně:

function timer() {
    function startTimer() {
        let timer = time;
        let minutes = 0;
        let seconds = 0;

        let countDownInterval = setInterval(function () {
            minutes = parseInt(timer / 60, 10);
            seconds = parseInt(timer % 60, 10);

            minutes = minutes < 10 ? "0" + minutes : minutes;
            seconds = seconds < 10 ? "0" + seconds : seconds;

            timeElement.textContent = minutes + ":" + seconds;
            
            timer--;

        }, 1000);
    }

    startTimer();
}

Samotnou funkci pak zavoláme na začátku hry, funkce startGame bude vypadat takto:

function startGame() {
    time = 60;
    createPills();
    draw();
    timer();
}

Když si zkusíme hru spustit, tak vidíme, že nám časomíra hezky funguje. Teď se můžeme vrhnout na ukončení hry, zde mohou nastat dva scénáře – sesbíráme všechny předměty, nebo nám dojde čas.

Pojďme si v HTML vytvořit okno, ve kterém se bude zobrazovat zpráva o skončení hry.

<div id="end">
        <p id="message"></p>
        <button onclick="location.reload()">Hrát znovu</button>
</div>

Vytvoříme si div s ID end a do něj vložíme tag <p>, ve kterém se bude nacházet text a tag <button>, tedy tlačítko, na které klikneme, pokud budeme chtít hrát znovu. Do tlačítka vložíme poslouchač událostí (ano lze ho definovat takto v HTML, ale dělá se to jen v určitých případech). Tento poslouchač je nastavený na onclick a volá se v něm metoda na znovunačtení stránky. Při kliknutí na „Hrát znovu“ se tedy restartuje stránka, v našem případě je to nejjednodušší možnost, jak ukončit a nastartovat znovu hru. Samotné okno jako takové si musíme ještě nastylovat, pojďme tedy do style.css. Celé okno bude vypadat takto:

Poznámka 2020 03 31 202929

Napřed si nastylujeme tlačítko:

button {
    margin-top: 30px;
    padding: 20px 30px;
    font-size: 20px;
    border-radius: 60px;
    border: 5px solid #ffc04b;
    font-family: 'Bitter', serif;
    color: white;
    background: linear-gradient(to bottom, #275786, #0e234d);
    text-shadow: 3px 3px 5px rgba(0, 0, 0, 0.4);
    box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.4);
}

Pomocí margin a padding nastavíme pozici a velikost tlačítka. Font-size nám určuje velikost fontu. Tlačítko má kolem sebe zlatý rámeček, ten nastavíme pomocí vlastnosti border a border-radius zařídí zaoblení rámečku. Pro písmo zvolíme náš hlavní font pomocí font-family a barvu písma nastavíme na bílou pomocí color. Barvu pozadí nám zajistí vlastnost background, která má v sobě barevný přechod (linear-gradient). Pro hezčí efekt nastavíme textu (text-shadow) i celému tlačítku (box-shadow) stín.

Nyní se vrhneme na celé okno:

#end {
    width: 300px;
    height: 300px;
    border-radius: 10px;
    color: white;
    background-color: #28529d;
    border: 5px solid #ffc04b;
    font-size: 20px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    display: none;
}

Oknu nastavíme velikost pomocí vlastností width a height. A aby byl zhruba ve středu stránky, nastavíme mu absolutní pozici (vlastnost position), díky tomu ho můžeme ručně posunout tam, kam potřebujeme, to uděláme pomocí vlastností top, left a transform. Poslední vlastnost display nám říká, že element se nebude zobrazovat. Zobrazíme ho pomocí JavaScriptu.

V JavaScriptu si vytvoříme 2 proměnné – endElement a endMessage.

let endElement = document.getElementById("end");
let endMessage = document.getElementById("message");

endElement budeme ve vhodnou chvíli zobrazovat (změníš hodnotu vlastnosti display) a do endMessage budeme vkládat zprávu. Na samotné zakončení si vytvoříme samostatnou funkci s názvem endGame:

function endGame(type, winTime) {
}

Tato funkce přebírá 2 parametry – type (jestli jsme vyhráli nebo prohráli) a winTime (při výhře chceme zobrazit čas). Ve funkci budou dvě podmínky:

function endGame(type, winTime) {
    if (type === "win") {
      endElement.style.display = "block";
      endMessage.textContent = `Vyhráli jste! Sesbírali jste všechny vitamíny za ${time - winTime} sekund.`;
    }
   
    if (type === "loss") {
      endElement.style.display = "block";
      endMessage.textContent = `Prohráli jste! Nestihli jste sesbírat všechny vitamíny. Zkuste to znovu.`;
    }
}

Jedna pro výhru a jedna pro prohru. Uvnitř každé podmínky je potom změna vlastnosti display, která nám zajistí zobrazení okna a vložení textu do zprávy. U výhry máme ještě malou aritmetickou operaci - ${time - winTime}. Od našeho základního času odečítáme čas z časomíry, tím pádem nám vyjde, jak dlouho nám trvalo sesbírání předmětů.

Funkci poté zavoláme přímo v časovači a rozhodujeme se opět pomocí dvou podmínek:

if (score === 6) {
    clearInterval(countDownInterval);
    endGame("win", timer);
}

if (timer == 0) {
    clearInterval(countDownInterval);
    endGame("loss");
}

Buď jsme sesbírali všechny předměty a skóre se bude rovnat 6 (nebo 7, pokud máš splnění dobrovolný úkol s čajem 😊), nebo se nám nepovede vše sesbírat do časového limitu a hodnota v proměnné timer se bude rovnat 0. V každé podmínce je vložená funkce clearInterval, která nám zastaví časovač. Funkce timer po úpravě vypadá takto:

function timer() {
    function startTimer() {
        let timer = time;
        let minutes = 0;
        let seconds = 0;

        let countDownInterval = setInterval(function () {
            minutes = parseInt(timer / 60, 10);
            seconds = parseInt(timer % 60, 10);

            minutes = minutes < 10 ? "0" + minutes : minutes;
            seconds = seconds < 10 ? "0" + seconds : seconds;

            //výhra
            if (score === 6) {
                clearInterval(countDownInterval);
                endGame("win", timer);
            }

            //prohra
            if (timer == 0) {
                clearInterval(countDownInterval);
                endGame("loss");
            }

            timeElement.textContent = minutes + ":" + seconds;

            timer--;

        }, 1000);
    }

    startTimer();
}

Nyní si zkus hru spustit a vyhrát/prohrát. 😊 Kód z dnešní lekce najdeš zde.

Na závěr

A jsme … na konci. Za celé Czechitas ti gratuluji! Právě jsi dokončil/a naši 11 denní výzvu. Už zvládáš základy programování:

  • Proměnné
  • Podmínky
  • Cykly
  • Pole
  • Funkce

Umíš se základy HTML a CSS a máš naprogramováno více než 200 řádků kódu. Pokud ses v některých částech nechytal/a, je to naprosto v pořádku. Když budeš chtít, můžeš si danou část projít znovu, články nezmizí.

Jak se ti tato forma vzdělávání líbila? Vyplň nám ZPĚTNOU VAZBU, at víme co zlepšit pro příště. :)

Předcházející den