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 rakentamamme 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 pilkomme tämän termin osiin, 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, johon haluamme reagoida koodilla, mutta emme tiedä, milloin se tapahtuu.
Tapa, jolla merkitsemme koodin osan, jonka haluamme suorittaa, on luoda funktio. Kun ajattelemme proseduraalista ohjelmointia, funktiot suoritetaan tietyssä järjestyksessä. Sama pätee tapahtumapohjaiseen ohjelmointiin. Ero on siinä, miten funktiot kutsutaan.
Tapahtumien (napin painaminen, kirjoittaminen jne.) käsittelemiseksi rekisteröimme tapahtumakuuntelijoita. Tapahtumakuuntelija on funktio, joka odottaa 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-metodia ja tarjoamalla suoritettavan funktion.
NOTE: On syytä korostaa, että tapahtumakuuntelijoiden luomiseen on monia tapoja. Voit käyttää anonyymejä funktioita tai luoda nimettyjä. Voit käyttää erilaisia oikoteitä, kuten asettamalla
click
-ominaisuuden tai käyttämälläaddEventListener
-metodia. Harjoituksessamme keskitymmeaddEventListener
-metodiin 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 osan tapahtumista. Tässä muutamia yleisiä (mukaan lukien kaksi, joita käytämme pelimme luomisessa):
- click: Käyttäjä klikkasi jotain, yleensä painiketta 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 aloituspainiketta ja saa kirjoitettavakseen lainauksen
- Pelaaja kirjoittaa lainauksen mahdollisimman nopeasti tekstikenttään
- Jokaisen sanan valmistuttua 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 terminaali 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
- Aloituspainike
Jokaiselle näistä tarvitaan ID:t, 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 isännöi sovellustasi paikallisesti ja päivittää selaimen aina, kun tallennat.
- Asenna Live Server seuraamalla linkkiä ja klikkaamalla Install
- Selaimesi kehottaa sinua avaamaan Visual Studio Coden, ja Visual Studio Code kehottaa sinua suorittamaan asennuksen
- Käynnistä Visual Studio Code uudelleen, jos sitä pyydetään
- Kun laajennus on asennettu, paina 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 ydinmuotoilua 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, keskitytään 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, kuten reseptissä, tässä on, mitä tarvitsemme:
- Taulukko, joka sisältää kaikki lainaukset
- Tyhjä taulukko, johon tallennetaan nykyisen lainauksen sanat
- Tila, jossa säilytetään pelaajan kirjoittaman sanan indeksi
- Aika, jolloin pelaaja klikkasi aloituspainiketta
Tarvitsemme myös viittaukset käyttöliittymä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 koodissa milloin tahansa käyttämällä
document.getElementById
. Koska viittaamme näihin elementteihin säännöllisesti, vältämme kirjoitusvirheitä merkkijonoissa käyttämällä vakioita. Kehykset, kuten Vue.js tai React, voivat auttaa sinua hallitsemaan koodin keskittämistä paremmin.
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 aloituspainiketta. Tietenkään emme tiedä, milloin hän klikkaa sitä. Tässä kohtaa tapahtumakuuntelija astuu kuvaan. Tapahtumakuuntelija antaa meidän kuunnella jotain tapahtumaa ja suorittaa koodia vastauksena. Meidän tapauksessamme haluamme suorittaa koodia, kun käyttäjä klikkaa aloituspainiketta.
Kun käyttäjä klikkaa start, meidän täytyy valita lainaus, asettaa käyttöliittymä ja aloittaa sanan ja ajan seuranta. Alla on JavaScript, joka sinun täytyy lisätä; 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-metodien avulla voimme valita satunnaisesti lainauksen
quotes
-taulukosta - Muunnamme
quote
-muuttujanwords
-taulukoksi, jotta voimme seurata pelaajan kirjoittamaa sanaa wordIndex
asetetaan arvoon 0, koska pelaaja aloittaa ensimmäisestä sanasta
- Math.floor- ja Math.random-metodien avulla voimme valita satunnaisesti lainauksen
- Käyttöliittymän asettaminen
- Luodaan
spanWords
-taulukko, joka sisältää jokaisen sananspan
-elementissä- 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 korostuu 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 nykytilan. Lisää script.js-tiedoston loppuun seuraava koodi. 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", jossa tarkistamme, onko lainaus valmis, sana valmis, sana oikein vai onko kyseessä 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ä kirjoitettu oikein (mutta ei valmis), jos
currentWord
alkaatypedValue
-arvolla- Varmistetaan, että
typedValueElement
näkyy oletuksena tyhjentämälläclassName
- Varmistetaan, että
- Jos pääsemme tähän asti, kyseessä on virhe
- 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ä. Tutki viestejä ja debuggaa tarvittaessa.
Klikkaa start ja ala kirjoittaa! Sen pitäisi näyttää hieman samalta kuin aiemmin näkemämme animaatio.
🚀 Haaste
Lisää toiminnallisuutta
- Poista
input
-tapahtumakuuntelija käytöstä, kun peli on valmis, ja ota se uudelleen käyttöön, kun painiketta klikataan - Poista tekstikenttä käytöstä, kun pelaaja suorittaa lainauksen
- Näytä modaalidialogi onnistumisviestillä
- Tallenna huippupisteet 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. Vaikka pyrimme tarkkuuteen, huomioithan, että automaattiset käännökset voivat sisältää virheitä tai epätarkkuuksia. Alkuperäinen asiakirja sen alkuperäisellä kielellä tulisi pitää ensisijaisena lähteenä. Kriittisen tiedon osalta suositellaan ammattimaista ihmiskäännöstä. Emme ole vastuussa väärinkäsityksistä tai virhetulkinnoista, jotka johtuvat tämän käännöksen käytöstä.