18 KiB
Vytvoření hry pomocí událostí
Kvíz před přednáškou
Programování řízené událostmi
Při vytváření aplikace prohlížeče poskytujeme uživateli grafické uživatelské rozhraní (GUI), které může použít při interakci s tím, co jsme vytvořili. Nejčastějším způsobem interakce s prohlížečem je klikání a psaní do různých prvků. Výzvou, které čelíme jako vývojáři, je, že nevíme, kdy tyto operace provedou!
Programování řízené událostmi je název pro typ programování, který potřebujeme k vytvoření našeho GUI. Pokud tuto frázi trochu rozebereme, zjistíme, že klíčovým slovem je zde událost. Událost je podle Merriam-Webster definována jako „něco, co se stane“. To dokonale popisuje naši situaci. Víme, že se něco stane, na co chceme reagovat spuštěním kódu, ale nevíme, kdy k tomu dojde.
Část kódu, kterou chceme spustit, označíme vytvořením funkce. Když přemýšlíme o procedurálním programování, funkce se volají ve specifickém pořadí. Totéž platí i pro programování řízené událostmi. Rozdíl je v tom, jak budou funkce volány.
Pro zpracování událostí (klikání na tlačítka, psaní atd.) registrujeme posluchače událostí. Posluchač událostí je funkce, která čeká na výskyt události a reaguje na ni spuštěním kódu. Posluchači událostí mohou aktualizovat uživatelské rozhraní, provádět volání na server nebo cokoliv jiného, co je potřeba udělat v reakci na akci uživatele. Posluchače událostí přidáváme pomocí addEventListener a poskytnutím funkce, která se má spustit.
NOTE: Stojí za zmínku, že existuje mnoho způsobů, jak vytvořit posluchače událostí. Můžete použít anonymní funkce nebo vytvořit pojmenované. Můžete použít různé zkratky, jako je nastavení vlastnosti
click
, nebo použítaddEventListener
. V našem cvičení se zaměříme naaddEventListener
a anonymní funkce, protože je to pravděpodobně nejběžnější technika, kterou weboví vývojáři používají. Je také nejflexibilnější, protožeaddEventListener
funguje pro všechny události a název události lze zadat jako parametr.
Běžné události
Existuje desítky událostí, které můžete poslouchat při vytváření aplikace. Prakticky cokoliv, co uživatel na stránce udělá, vyvolá událost, což vám dává velkou moc zajistit, že dostane požadovaný zážitek. Naštěstí obvykle budete potřebovat jen malý počet událostí. Zde je několik běžných (včetně dvou, které použijeme při vytváření naší hry):
- click: Uživatel na něco klikl, obvykle na tlačítko nebo odkaz
- contextmenu: Uživatel klikl pravým tlačítkem myši
- select: Uživatel označil nějaký text
- input: Uživatel zadal nějaký text
Vytvoření hry
Vytvoříme hru, abychom prozkoumali, jak události fungují v JavaScriptu. Naše hra otestuje schopnost hráče psát, což je jedna z nejvíce podceňovaných dovedností, kterou by měl mít každý vývojář. Všichni bychom měli trénovat psaní! Obecný průběh hry bude vypadat takto:
- Hráč klikne na tlačítko start a zobrazí se mu citát k opsání
- Hráč co nejrychleji napíše citát do textového pole
- Jakmile dokončí jedno slovo, další se zvýrazní
- Pokud hráč udělá překlep, textové pole se zbarví červeně
- Když hráč dokončí citát, zobrazí se zpráva o úspěchu s uplynulým časem
Pojďme vytvořit naši hru a naučit se něco o událostech!
Struktura souborů
Budeme potřebovat celkem tři soubory: index.html, script.js a style.css. Začněme jejich nastavením, abychom si usnadnili práci.
- Vytvořte novou složku pro svou práci otevřením konzole nebo terminálu a zadáním následujícího příkazu:
# Linux or macOS
mkdir typing-game && cd typing-game
# Windows
md typing-game && cd typing-game
- Otevřete Visual Studio Code
code .
- Přidejte do složky ve Visual Studio Code tři soubory s následujícími názvy:
- index.html
- script.js
- style.css
Vytvoření uživatelského rozhraní
Pokud prozkoumáme požadavky, víme, že budeme potřebovat několik prvků na naší HTML stránce. Je to něco jako recept, kde potřebujeme nějaké ingredience:
- Místo pro zobrazení citátu, který má uživatel opsat
- Místo pro zobrazení zpráv, jako je zpráva o úspěchu
- Textové pole pro psaní
- Tlačítko start
Každý z těchto prvků bude potřebovat ID, abychom s nimi mohli pracovat v našem JavaScriptu. Přidáme také odkazy na soubory CSS a JavaScript, které vytvoříme.
Vytvořte nový soubor s názvem index.html. Přidejte následující HTML:
<!-- inside index.html -->
<html>
<head>
<title>Typing game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Typing game!</h1>
<p>Practice your typing skills with a quote from Sherlock Holmes. Click **start** to begin!</p>
<p id="quote"></p> <!-- This will display our quote -->
<p id="message"></p> <!-- This will display any status messages -->
<div>
<input type="text" aria-label="current word" id="typed-value" /> <!-- The textbox for typing -->
<button type="button" id="start">Start</button> <!-- To start the game -->
</div>
<script src="script.js"></script>
</body>
</html>
Spuštění aplikace
Vždy je nejlepší vyvíjet iterativně, abychom viděli, jak věci vypadají. Spusťme naši aplikaci. Existuje skvělý doplněk pro Visual Studio Code s názvem Live Server, který bude hostovat vaši aplikaci lokálně a aktualizovat prohlížeč pokaždé, když uložíte.
- Nainstalujte Live Server podle odkazu a kliknutím na Install
- Prohlížeč vás vyzve k otevření Visual Studio Code a poté vás Visual Studio Code vyzve k provedení instalace
- Restartujte Visual Studio Code, pokud budete vyzváni
- Po instalaci klikněte ve Visual Studio Code na Ctrl-Shift-P (nebo Cmd-Shift-P) pro otevření příkazové palety
- Zadejte Live Server: Open with Live Server
- Live Server začne hostovat vaši aplikaci
- Otevřete prohlížeč a přejděte na https://localhost:5500
- Nyní byste měli vidět stránku, kterou jste vytvořili!
Přidejme nějakou funkcionalitu.
Přidání CSS
S naším HTML vytvořeným přidáme CSS pro základní stylování. Potřebujeme zvýraznit slovo, které by měl hráč psát, a obarvit textové pole, pokud to, co napsal, není správné. To uděláme pomocí dvou tříd.
Vytvořte nový soubor s názvem style.css a přidejte následující syntaxi.
/* inside style.css */
.highlight {
background-color: yellow;
}
.error {
background-color: lightcoral;
border: red;
}
✅ Co se týče CSS, můžete si stránku rozvrhnout, jak chcete. Věnujte trochu času a udělejte stránku vizuálně přitažlivější:
- Vyberte jiný font
- Obarvěte nadpisy
- Změňte velikost prvků
JavaScript
S naším uživatelským rozhraním vytvořeným je čas zaměřit naši pozornost na JavaScript, který poskytne logiku. Rozdělíme to na několik kroků:
Nejprve ale vytvořte nový soubor s názvem script.js.
Přidání konstant
Budeme potřebovat několik položek, které nám usnadní programování. Opět, podobně jako recept, zde je to, co budeme potřebovat:
- Pole se seznamem všech citátů
- Prázdné pole pro uložení všech slov aktuálního citátu
- Prostor pro uložení indexu slova, které hráč aktuálně píše
- Čas, kdy hráč klikl na start
Budeme také chtít odkazy na prvky uživatelského rozhraní:
- Textové pole (typed-value)
- Zobrazení citátu (quote)
- Zpráva (message)
// inside script.js
// all of our quotes
const quotes = [
'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.',
'There is nothing more deceptive than an obvious fact.',
'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.',
'I never make exceptions. An exception disproves the rule.',
'What one man can invent another can discover.',
'Nothing clears up a case so much as stating it to another person.',
'Education never ends, Watson. It is a series of lessons, with the greatest for the last.',
];
// store the list of words and the index of the word the player is currently typing
let words = [];
let wordIndex = 0;
// the starting time
let startTime = Date.now();
// page elements
const quoteElement = document.getElementById('quote');
const messageElement = document.getElementById('message');
const typedValueElement = document.getElementById('typed-value');
✅ Přidejte do své hry více citátů
NOTE: Prvky můžeme kdykoliv v kódu získat pomocí
document.getElementById
. Protože se na tyto prvky budeme pravidelně odkazovat, vyhneme se překlepům ve stringových literálech použitím konstant. Frameworky jako Vue.js nebo React vám mohou pomoci lépe centralizovat váš kód.
Podívejte se na video o používání const
, let
a var
🎥 Klikněte na obrázek výše pro video o proměnných.
Přidání logiky spuštění
Pro spuštění hry hráč klikne na start. Samozřejmě nevíme, kdy na start klikne. Zde přichází na řadu posluchač událostí. Posluchač událostí nám umožní poslouchat, kdy se něco stane (událost), a reagovat na to spuštěním kódu. V našem případě chceme spustit kód, když uživatel klikne na start.
Když uživatel klikne na start, musíme vybrat citát, nastavit uživatelské rozhraní a připravit sledování aktuálního slova a času. Níže je JavaScript, který budete muset přidat; rozebereme ho hned po bloku skriptu.
// at the end of script.js
document.getElementById('start').addEventListener('click', () => {
// get a quote
const quoteIndex = Math.floor(Math.random() * quotes.length);
const quote = quotes[quoteIndex];
// Put the quote into an array of words
words = quote.split(' ');
// reset the word index for tracking
wordIndex = 0;
// UI updates
// Create an array of span elements so we can set a class
const spanWords = words.map(function(word) { return `<span>${word} </span>`});
// Convert into string and set as innerHTML on quote display
quoteElement.innerHTML = spanWords.join('');
// Highlight the first word
quoteElement.childNodes[0].className = 'highlight';
// Clear any prior messages
messageElement.innerText = '';
// Setup the textbox
// Clear the textbox
typedValueElement.value = '';
// set focus
typedValueElement.focus();
// set the event handler
// Start the timer
startTime = new Date().getTime();
});
Rozeberme si kód!
- Nastavení sledování slov
- Použití Math.floor a Math.random nám umožní náhodně vybrat citát z pole
quotes
- Převádíme
quote
na polewords
, abychom mohli sledovat slovo, které hráč aktuálně píše wordIndex
je nastaven na 0, protože hráč začne na prvním slově
- Použití Math.floor a Math.random nám umožní náhodně vybrat citát z pole
- Nastavení uživatelského rozhraní
- Vytvoříme pole
spanWords
, které obsahuje každé slovo uvnitř prvkuspan
- To nám umožní zvýraznit slovo na displeji
join
pole pro vytvoření řetězce, který můžeme použít k aktualizaciinnerHTML
naquoteElement
- To zobrazí citát hráči
- Nastavíme
className
prvního prvkuspan
nahighlight
, aby byl zvýrazněn žlutě - Vyčistíme
messageElement
nastaveníminnerText
na''
- Vytvoříme pole
- Nastavení textového pole
- Vymažeme aktuální
value
natypedValueElement
- Nastavíme
focus
natypedValueElement
- Vymažeme aktuální
- Spustíme časovač voláním
getTime
Přidání logiky psaní
Jak hráč píše, bude vyvolána událost input
. Tento posluchač událostí zkontroluje, zda hráč píše slovo správně, a zpracuje aktuální stav hry. Vraťte se do script.js a přidejte následující kód na konec. Rozebereme ho poté.
// at the end of script.js
typedValueElement.addEventListener('input', () => {
// Get the current word
const currentWord = words[wordIndex];
// get the current value
const typedValue = typedValueElement.value;
if (typedValue === currentWord && wordIndex === words.length - 1) {
// end of sentence
// Display success
const elapsedTime = new Date().getTime() - startTime;
const message = `CONGRATULATIONS! You finished in ${elapsedTime / 1000} seconds.`;
messageElement.innerText = message;
} else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) {
// end of word
// clear the typedValueElement for the new word
typedValueElement.value = '';
// move to the next word
wordIndex++;
// reset the class name for all elements in quote
for (const wordElement of quoteElement.childNodes) {
wordElement.className = '';
}
// highlight the new word
quoteElement.childNodes[wordIndex].className = 'highlight';
} else if (currentWord.startsWith(typedValue)) {
// currently correct
// highlight the next word
typedValueElement.className = '';
} else {
// error state
typedValueElement.className = 'error';
}
});
Rozeberme si kód! Začínáme tím, že získáme aktuální slovo a hodnotu, kterou hráč dosud napsal. Poté máme logiku ve stylu vodopádu, kde kontrolujeme, zda je citát dokončen, slovo dokončeno, slovo správné nebo (nakonec), zda je tam chyba.
- Citát je dokončen, což je indikováno tím, že
typedValue
je rovnocurrentWord
awordIndex
je rovno jednomu méně nežlength
words
- Vypočítáme
elapsedTime
odečtenímstartTime
od aktuálního času - Dělíme
elapsedTime
1 000, abychom převedli z milisekund na sekundy - Zobrazíme zprávu o úspěchu
- Vypočítáme
- Slovo je dokončeno, což je indikováno tím, že
typedValue
končí mezerou (konec slova) atypedValue
je rovnocurrentWord
- Nastavíme
value
natypedElement
na''
, abychom umožnili psaní dalšího slova - Zvýšíme
wordIndex
, abychom přešli na další slovo - Projdeme všechny
childNodes
quoteElement
a nastavímeclassName
na''
, abychom obnovili výchozí zobrazení - Nastavíme
className
aktuálního slova nahighlight
, abychom ho označili jako další slovo k napsání
- Nastavíme
- Slovo je aktuálně napsáno správně (ale není dokončeno), což je indikováno tím, že
currentWord
začínátypedValue
- Zajistíme, že
typedValueElement
je zobrazen jako výchozí, vymazánímclassName
- Zajistíme, že
- Pokud jsme se dostali až sem, máme chybu
- Nastavíme
className
natypedValueElement
naerror
- Nastavíme
Otestujte svou aplikaci
Dostali jste se na konec! Posledním krokem je zajistit, aby naše aplikace fungovala. Vyzkoušejte ji! Nebojte se, pokud se objeví chyby; všichni vývojáři mají chyby. Prozkoumejte zprávy a laděte podle potřeby.
Klikněte na start a začněte psát! Mělo by to vypadat trochu jako animace, kterou jsme viděli dříve.
🚀 Výzva
Přidejte více funkcionality
- Deaktivujte posluchač událostí
input
po dokončení a znovu ho aktivujte, když je kliknuto na tlačítko - Deaktivujte textové pole, když hráč dokončí citát
- Zobrazte modální dialogové okno se zprávou o úspěchu
- Ukládejte nejlepší skóre pomocí localStorage
Kvíz po přednášce
Přehled a samostudium
Projděte si všechny dostupné události, které má vývojář k dispozici prostřednictvím webového prohlížeče, a zamyslete se nad situacemi, ve kterých byste každou z nich použili.
Úkol
Vytvořte novou hru na klávesnici
Prohlášení:
Tento dokument byl přeložen pomocí služby AI pro překlady Co-op Translator. Ačkoli se snažíme o přesnost, mějte prosím na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Původní dokument v jeho původním jazyce by měl být považován za autoritativní zdroj. Pro důležité informace se doporučuje profesionální lidský překlad. Neodpovídáme za žádné nedorozumění nebo nesprávné interpretace vyplývající z použití tohoto překladu.