18 KiB
Pelin luominen tapahtumien avulla
Ennakkokysely
Tapahtumapohjainen ohjelmointi
Kun luomme selainpohjaisen sovelluksen, tarjoamme käyttäjälle graafisen käyttöliittymän (GUI), jonka avulla hän voi olla vuorovaikutuksessa luomamme kanssa. Yleisin tapa olla vuorovaikutuksessa selaimen kanssa on klikkaaminen ja kirjoittaminen eri elementteihin. Kehittäjänä kohtaamme haasteen: emme tiedä, milloin käyttäjä suorittaa nämä toiminnot!
Tapahtumapohjainen ohjelmointi on ohjelmointityyppi, jota tarvitsemme GUI:n luomiseen. Jos tarkastelemme tätä termiä tarkemmin, huomaamme, että ydin on sana tapahtuma. Tapahtuma määritellään Merriam-Websterin mukaan "joksikin, joka tapahtuu". Tämä kuvaa tilannettamme täydellisesti. Tiedämme, että jotain tulee tapahtumaan, ja haluamme suorittaa koodia vastauksena siihen, mutta emme tiedä, milloin se tapahtuu.
Tapa, jolla merkitsemme koodin osan, jonka haluamme suorittaa, on luoda funktio. Kun ajattelemme proseduraalista ohjelmointia, funktiot kutsutaan tietyssä järjestyksessä. Sama pätee tapahtumapohjaiseen ohjelmointiin. Erona on miten funktiot kutsutaan.
Tapahtumien (kuten napin painallusten tai kirjoittamisen) käsittelemiseksi rekisteröimme tapahtumakuuntelijoita. Tapahtumakuuntelija on funktio, joka kuuntelee tapahtuman tapahtumista ja suorittaa koodia vastauksena. Tapahtumakuuntelijat voivat päivittää käyttöliittymää, tehdä palvelinkutsuja tai mitä tahansa muuta, mitä käyttäjän toiminta vaatii. Lisäämme tapahtumakuuntelijan käyttämällä addEventListener-funktiota ja tarjoamalla suoritettavan funktion.
NOTE: On syytä huomata, että on olemassa lukuisia tapoja luoda tapahtumakuuntelijoita. Voit käyttää anonyymejä funktioita tai luoda nimettyjä. Voit käyttää erilaisia oikoteitä, kuten asettamalla
click
-ominaisuuden tai käyttämälläaddEventListener
-funktiota. Harjoituksessamme keskitymmeaddEventListener
-funktioon ja anonyymeihin funktioihin, koska se on todennäköisesti yleisin tekniikka, jota web-kehittäjät käyttävät. Se on myös joustavin, koskaaddEventListener
toimii kaikille tapahtumille, ja tapahtuman nimi voidaan antaa parametrina.
Yleisiä tapahtumia
Sovellusta luodessasi voit kuunnella kymmeniä tapahtumia. Käytännössä kaikki, mitä käyttäjä tekee sivulla, laukaisee tapahtuman, mikä antaa sinulle paljon valtaa varmistaa, että käyttäjä saa haluamasi kokemuksen. Onneksi tarvitset yleensä vain pienen joukon tapahtumia. Tässä muutamia yleisiä (mukaan lukien kaksi, joita käytämme pelimme luomisessa):
- click: Käyttäjä klikkasi jotain, yleensä nappia tai hyperlinkkiä
- contextmenu: Käyttäjä klikkasi hiiren oikeaa painiketta
- select: Käyttäjä valitsi tekstiä
- input: Käyttäjä syötti tekstiä
Pelin luominen
Luomme pelin tutkiaksemme, miten tapahtumat toimivat JavaScriptissä. Pelimme testaa pelaajan kirjoitustaitoa, joka on yksi aliarvostetuimmista taidoista, joita kaikilla kehittäjillä tulisi olla. Meidän kaikkien tulisi harjoitella kirjoittamista! Pelin yleinen kulku näyttää tältä:
- Pelaaja klikkaa aloitusnappia ja saa kirjoitettavakseen lainauksen
- Pelaaja kirjoittaa lainauksen mahdollisimman nopeasti tekstikenttään
- Kun jokainen sana on valmis, seuraava korostetaan
- Jos pelaaja tekee kirjoitusvirheen, tekstikenttä muuttuu punaiseksi
- Kun pelaaja suorittaa lainauksen, näytetään onnistumisviesti ja kulunut aika
Rakennetaan peli ja opitaan tapahtumista!
Tiedostorakenne
Tarvitsemme yhteensä kolme tiedostoa: index.html, script.js ja style.css. Aloitetaan niiden luomisesta, jotta työskentely olisi helpompaa.
- Luo uusi kansio työllesi avaamalla konsoli tai pääteikkuna ja suorittamalla seuraava komento:
# Linux or macOS
mkdir typing-game && cd typing-game
# Windows
md typing-game && cd typing-game
- Avaa Visual Studio Code
code .
- Lisää kansioon kolme tiedostoa Visual Studio Codessa seuraavilla nimillä:
- index.html
- script.js
- style.css
Käyttöliittymän luominen
Jos tarkastelemme vaatimuksia, tiedämme, että tarvitsemme HTML-sivullemme muutamia elementtejä. Tämä on vähän kuin resepti, jossa tarvitsemme ainesosia:
- Paikka, jossa näytetään käyttäjälle kirjoitettava lainaus
- Paikka, jossa näytetään viestejä, kuten onnistumisviesti
- Tekstikenttä kirjoittamista varten
- Aloitusnappi
Jokaiselle näistä annetaan ID, jotta voimme käsitellä niitä JavaScriptissä. Lisäämme myös viittaukset luotaviin CSS- ja JavaScript-tiedostoihin.
Luo uusi tiedosto nimeltä index.html. Lisää seuraava 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>
Sovelluksen käynnistäminen
On aina parasta kehittää iteratiivisesti ja tarkistaa, miltä asiat näyttävät. Käynnistetään sovellus. Visual Studio Codessa on upea laajennus nimeltä Live Server, joka sekä isännöi sovellustasi paikallisesti että päivittää selaimen aina, kun tallennat.
- Asenna Live Server seuraamalla linkkiä ja klikkaamalla Install
- Selain kehottaa sinua avaamaan Visual Studio Coden, ja Visual Studio Code kehottaa suorittamaan asennuksen
- Käynnistä Visual Studio Code uudelleen, jos sitä pyydetään
- Kun laajennus on asennettu, klikkaa Visual Studio Codessa Ctrl-Shift-P (tai Cmd-Shift-P) avataksesi komentopaletti
- Kirjoita Live Server: Open with Live Server
- Live Server alkaa isännöidä sovellustasi
- Avaa selain ja siirry osoitteeseen https://localhost:5500
- Näet nyt luomasi sivun!
Lisätään toiminnallisuutta.
Lisää CSS
Kun HTML on luotu, lisätään CSS perusmuotoilua varten. Meidän täytyy korostaa sana, jonka pelaajan tulisi kirjoittaa, ja värjätä tekstikenttä punaiseksi, jos kirjoitus on virheellinen. Teemme tämän kahdella luokalla.
Luo uusi tiedosto nimeltä style.css ja lisää seuraava syntaksi.
/* inside style.css */
.highlight {
background-color: yellow;
}
.error {
background-color: lightcoral;
border: red;
}
✅ CSS:n osalta voit asettaa sivusi ulkoasun haluamallasi tavalla. Käytä hetki aikaa ja tee sivusta houkuttelevampi:
- Valitse eri fontti
- Väritä otsikot
- Muuta elementtien kokoa
JavaScript
Kun käyttöliittymä on luotu, keskitymme JavaScriptiin, joka tarjoaa logiikan. Jaamme tämän muutamaan vaiheeseen:
Mutta ensin, luo uusi tiedosto nimeltä script.js.
Lisää vakioarvot
Tarvitsemme muutamia asioita, jotka helpottavat ohjelmointia. Jälleen, vähän kuin resepti, tässä on, mitä tarvitsemme:
- Taulukko, joka sisältää kaikki lainaukset
- Tyhjä taulukko, johon tallennetaan nykyisen lainauksen sanat
- Paikka, jossa säilytetään pelaajan kirjoittaman sanan indeksi
- Aika, jolloin pelaaja klikkasi aloitusta
Tarvitsemme myös viittaukset käyttöliittymän elementteihin:
- Tekstikenttä (typed-value)
- Lainauksen näyttö (quote)
- Viesti (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');
✅ Lisää peliisi lisää lainauksia
NOTE: Voimme hakea elementit aina, kun haluamme, käyttämällä
document.getElementById
. Koska viittaamme näihin elementteihin säännöllisesti, vältämme kirjoitusvirheitä käyttämällä vakioita. Kehykset, kuten Vue.js tai React, voivat auttaa sinua hallitsemaan koodiasi keskitetysti.
Katso minuutin mittainen video const
, let
ja var
-muuttujien käytöstä
🎥 Klikkaa yllä olevaa kuvaa katsoaksesi videon muuttujista.
Lisää aloituslogiikka
Pelin aloittamiseksi pelaaja klikkaa aloitusnappia. Tietenkään emme tiedä, milloin hän klikkaa sitä. Tässä kohtaa tapahtumakuuntelija tulee mukaan. Tapahtumakuuntelija antaa meille mahdollisuuden kuunnella jotain tapahtumaa ja suorittaa koodia vastauksena. Meidän tapauksessamme haluamme suorittaa koodia, kun käyttäjä klikkaa aloitusta.
Kun käyttäjä klikkaa aloitusta, meidän täytyy valita lainaus, asettaa käyttöliittymä ja aloittaa sanan ja ajan seuranta. Alla on JavaScript, jonka tarvitset lisätäksesi; käsittelemme sitä tarkemmin koodilohkon jälkeen.
// 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();
});
Käydään koodi läpi!
- Sanan seurannan asettaminen
- Math.floor- ja Math.random-funktioiden avulla voimme valita satunnaisesti lainauksen
quotes
-taulukosta - Muutamme
quote
-muuttujanwords
-taulukoksi, jotta voimme seurata pelaajan kirjoittamaa sanaa wordIndex
asetetaan arvoon 0, koska pelaaja aloittaa ensimmäisestä sanasta
- Math.floor- ja Math.random-funktioiden avulla voimme valita satunnaisesti lainauksen
- Käyttöliittymän asettaminen
- Luodaan
spanWords
-taulukko, joka sisältää jokaisen sananspan
-elementin sisällä- Tämä mahdollistaa sanan korostamisen näytöllä
join
-metodilla luodaan merkkijono, jota käytetäänquoteElement
-elementininnerHTML
-arvon päivittämiseen- Tämä näyttää lainauksen pelaajalle
- Asetetaan ensimmäisen
span
-elementinclassName
arvoksihighlight
, jotta se korostetaan keltaiseksi - Tyhjennetään
messageElement
asettamallainnerText
arvoksi''
- Luodaan
- Tekstikentän asettaminen
- Tyhjennetään nykyinen
value
typedValueElement
-elementistä - Asetetaan
focus
typedValueElement
-elementtiin
- Tyhjennetään nykyinen
- Ajastimen käynnistäminen kutsumalla
getTime
Lisää kirjoituslogiikka
Kun pelaaja kirjoittaa, input
-tapahtuma laukaistaan. Tämä tapahtumakuuntelija tarkistaa, kirjoittaako pelaaja sanan oikein, ja käsittelee pelin nykyisen tilan. Palataan script.js-tiedostoon ja lisää seuraava koodi loppuun. Käsittelemme sitä tarkemmin koodilohkon jälkeen.
// 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';
}
});
Käydään koodi läpi! Aloitamme hakemalla nykyisen sanan ja pelaajan tähän mennessä kirjoittaman arvon. Sitten käytämme vesiputouslogiikkaa tarkistaaksemme, onko lainaus valmis, sana valmis, sana oikein vai (lopuksi) onko virhe.
- Lainaus on valmis, jos
typedValue
on yhtä kuincurrentWord
jawordIndex
on yhtä kuinwords
-taulukon pituus miinus yksi- Lasketaan
elapsedTime
vähentämällästartTime
nykyisestä ajasta - Jaetaan
elapsedTime
luvulla 1 000, jotta se muunnetaan millisekunneista sekunneiksi - Näytetään onnistumisviesti
- Lasketaan
- Sana on valmis, jos
typedValue
päättyy välilyöntiin (sanan loppu) jatypedValue
on yhtä kuincurrentWord
- Asetetaan
typedElement
-elementinvalue
arvoksi''
, jotta seuraava sana voidaan kirjoittaa - Kasvatetaan
wordIndex
-arvoa siirtyäksemme seuraavaan sanaan - Käydään läpi kaikki
quoteElement
-elementinchildNodes
-solmut ja asetetaan niidenclassName
arvoksi''
, jotta ne palautuvat oletusnäkymään - Asetetaan nykyisen sanan
className
arvoksihighlight
, jotta se merkitään seuraavaksi kirjoitettavaksi sanaksi
- Asetetaan
- Sana on tällä hetkellä oikein kirjoitettu (mutta ei valmis), jos
currentWord
alkaatypedValue
-arvolla- Varmistetaan, että
typedValueElement
näkyy oletusarvoisena tyhjentämälläclassName
- Varmistetaan, että
- Jos pääsemme tähän asti, olemme tehneet virheen
- Asetetaan
typedValueElement
-elementinclassName
arvoksierror
- Asetetaan
Testaa sovellustasi
Olet päässyt loppuun! Viimeinen vaihe on varmistaa, että sovelluksemme toimii. Kokeile sitä! Älä huoli, jos virheitä ilmenee; kaikilla kehittäjillä on virheitä. Tarkastele viestejä ja korjaa tarvittaessa.
Klikkaa aloita ja ala kirjoittaa! Sen pitäisi näyttää vähän tältä animaatiolta, jonka näimme aiemmin.
🚀 Haaste
Lisää toiminnallisuutta
- Poista
input
-tapahtumakuuntelija käytöstä, kun peli on valmis, ja ota se uudelleen käyttöön, kun nappia klikataan - Poista tekstikenttä käytöstä, kun pelaaja suorittaa lainauksen
- Näytä modaalidialogi onnistumisviestillä
- Tallenna parhaat tulokset käyttämällä localStorage
Luentojälkeinen kysely
Kertaus ja itseopiskelu
Lue lisää kaikista tapahtumista, jotka ovat kehittäjän käytettävissä verkkoselaimen kautta, ja pohdi tilanteita, joissa käyttäisit kutakin niistä.
Tehtävä
Vastuuvapauslauseke:
Tämä asiakirja on käännetty käyttämällä tekoälypohjaista käännöspalvelua Co-op Translator. Pyrimme tarkkuuteen, mutta huomioithan, että automaattiset käännökset voivat sisältää virheitä tai epätarkkuuksia. Alkuperäistä asiakirjaa sen alkuperäisellä kielellä tulee pitää ensisijaisena lähteenä. Kriittisen tiedon osalta suositellaan ammattimaista ihmiskääntämistä. Emme ole vastuussa väärinkäsityksistä tai virhetulkinnoista, jotka johtuvat tämän käännöksen käytöstä.