You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/sv/4-typing-game/typing-game/README.md

18 KiB

Skapa ett spel med hjälp av händelser

Förkunskapstest

Förkunskapstest

Händelsestyrd programmering

När vi skapar en webbläsarbaserad applikation tillhandahåller vi ett grafiskt användargränssnitt (GUI) som användaren kan använda för att interagera med det vi har byggt. Det vanligaste sättet att interagera med webbläsaren är genom att klicka och skriva i olika element. Utmaningen vi står inför som utvecklare är att vi inte vet när användaren kommer att utföra dessa operationer!

Händelsestyrd programmering är namnet på den typ av programmering vi behöver använda för att skapa vårt GUI. Om vi bryter ner detta uttryck lite ser vi att kärnordet här är händelse. Händelse, enligt Merriam-Webster, definieras som "något som händer". Detta beskriver vår situation perfekt. Vi vet att något kommer att hända som vi vill köra viss kod som svar på, men vi vet inte när det kommer att ske.

Sättet vi markerar en kodsektion som vi vill köra är genom att skapa en funktion. När vi tänker på procedurprogrammering anropas funktioner i en specifik ordning. Samma sak gäller för händelsestyrd programmering. Skillnaden är hur funktionerna kommer att anropas.

För att hantera händelser (knapptryckningar, inmatning osv.) registrerar vi händelselyssnare. En händelselyssnare är en funktion som lyssnar efter att en händelse inträffar och körs som svar. Händelselyssnare kan uppdatera användargränssnittet, göra anrop till servern eller vad som helst som behöver göras som svar på användarens handling. Vi lägger till en händelselyssnare genom att använda addEventListener och tillhandahålla en funktion som ska köras.

NOTE: Det är värt att påpeka att det finns många sätt att skapa händelselyssnare. Du kan använda anonyma funktioner eller skapa namngivna. Du kan använda olika genvägar, som att ställa in click-egenskapen, eller använda addEventListener. I vår övning kommer vi att fokusera på addEventListener och anonyma funktioner, eftersom det förmodligen är den vanligaste tekniken som webbutvecklare använder. Det är också det mest flexibla, eftersom addEventListener fungerar för alla händelser och händelsenamnet kan tillhandahållas som en parameter.

Vanliga händelser

Det finns dussintals händelser som du kan lyssna på när du skapar en applikation. I princip allt en användare gör på en sida utlöser en händelse, vilket ger dig mycket makt att säkerställa att de får den upplevelse du önskar. Lyckligtvis behöver du vanligtvis bara ett fåtal händelser. Här är några vanliga (inklusive de två vi kommer att använda när vi skapar vårt spel):

  • click: Användaren klickade på något, vanligtvis en knapp eller hyperlänk
  • contextmenu: Användaren högerklickade
  • select: Användaren markerade text
  • input: Användaren skrev in text

Skapa spelet

Vi ska skapa ett spel för att utforska hur händelser fungerar i JavaScript. Vårt spel kommer att testa spelarens skrivförmåga, vilket är en av de mest underskattade färdigheterna som alla utvecklare borde ha. Vi borde alla öva på att skriva! Den allmänna flödet för spelet kommer att se ut så här:

  • Spelaren klickar på startknappen och får en text att skriva
  • Spelaren skriver texten så snabbt som möjligt i en textruta
    • När varje ord är klart markeras nästa
    • Om spelaren gör ett skrivfel blir textrutan röd
    • När spelaren slutför texten visas ett framgångsmeddelande med den förflutna tiden

Låt oss bygga vårt spel och lära oss om händelser!

Filstruktur

Vi kommer att behöva totalt tre filer: index.html, script.js och style.css. Låt oss börja med att ställa in dessa för att göra livet lite enklare för oss.

  • Skapa en ny mapp för ditt arbete genom att öppna en konsol eller terminal och köra följande kommando:
# Linux or macOS
mkdir typing-game && cd typing-game

# Windows
md typing-game && cd typing-game
  • Öppna Visual Studio Code
code .
  • Lägg till tre filer i mappen i Visual Studio Code med följande namn:
    • index.html
    • script.js
    • style.css

Skapa användargränssnittet

Om vi utforskar kraven vet vi att vi kommer att behöva några element på vår HTML-sida. Detta är lite som ett recept, där vi behöver några ingredienser:

  • Något för att visa texten som användaren ska skriva
  • Något för att visa meddelanden, som ett framgångsmeddelande
  • En textruta för att skriva
  • En startknapp

Varje av dessa kommer att behöva ID:n så att vi kan arbeta med dem i vår JavaScript. Vi kommer också att lägga till referenser till CSS- och JavaScript-filerna vi ska skapa.

Skapa en ny fil med namnet index.html. Lägg till följande 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>

Starta applikationen

Det är alltid bäst att utveckla iterativt för att se hur saker ser ut. Låt oss starta vår applikation. Det finns en fantastisk tillägg för Visual Studio Code som heter Live Server som både kommer att vara värd för din applikation lokalt och uppdatera webbläsaren varje gång du sparar.

  • Installera Live Server genom att följa länken och klicka på Install
    • Du kommer att bli ombedd av webbläsaren att öppna Visual Studio Code och sedan av Visual Studio Code att utföra installationen
    • Starta om Visual Studio Code om det behövs
  • När det är installerat, i Visual Studio Code, klicka på Ctrl-Shift-P (eller Cmd-Shift-P) för att öppna kommandopaletten
  • Skriv Live Server: Open with Live Server
    • Live Server kommer att börja vara värd för din applikation
  • Öppna en webbläsare och navigera till https://localhost:5500
  • Du bör nu se sidan du skapade!

Låt oss lägga till lite funktionalitet.

Lägg till CSS

Med vår HTML skapad, låt oss lägga till CSS för grundläggande styling. Vi behöver markera det ord som spelaren ska skriva och färga textrutan om det de har skrivit är felaktigt. Vi gör detta med två klasser.

Skapa en ny fil med namnet style.css och lägg till följande syntax.

/* inside style.css */
.highlight {
  background-color: yellow;
}

.error {
  background-color: lightcoral;
  border: red;
}

När det gäller CSS kan du layouta din sida hur du vill. Ta lite tid och gör sidan mer tilltalande:

  • Välj ett annat typsnitt
  • Färglägg rubrikerna
  • Ändra storlek på element

JavaScript

Med vårt användargränssnitt skapat är det dags att fokusera på JavaScript som kommer att tillhandahålla logiken. Vi kommer att dela upp detta i några steg:

Men först, skapa en ny fil med namnet script.js.

Lägg till konstanterna

Vi kommer att behöva några saker för att göra vårt programmeringsliv lite enklare. Återigen, likt ett recept, här är vad vi behöver:

  • En array med en lista över alla citat
  • En tom array för att lagra alla ord för det aktuella citatet
  • Ett utrymme för att lagra indexet för det ord som spelaren för närvarande skriver
  • Tiden då spelaren klickade på start

Vi kommer också att vilja ha referenser till användargränssnittselementen:

  • Textrutan (typed-value)
  • Citatvisningen (quote)
  • Meddelandet (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');

Lägg gärna till fler citat i ditt spel

NOTE: Vi kan hämta elementen när som helst i koden genom att använda document.getElementById. Eftersom vi kommer att hänvisa till dessa element regelbundet kommer vi att undvika skrivfel med strängar genom att använda konstanter. Ramverk som Vue.js eller React kan hjälpa dig att bättre hantera centralisering av din kod.

Ta en minut och titta på en video om att använda const, let och var.

Typer av variabler

🎥 Klicka på bilden ovan för en video om variabler.

Lägg till startlogik

För att börja spelet kommer spelaren att klicka på start. Självklart vet vi inte när de kommer att klicka på start. Det är här en händelselyssnare kommer in i bilden. En händelselyssnare gör att vi kan lyssna efter att något inträffar (en händelse) och köra kod som svar. I vårt fall vill vi köra kod när användaren klickar på start.

När användaren klickar på start behöver vi välja ett citat, ställa in användargränssnittet och ställa in spårning för det aktuella ordet och tidtagningen. Nedan är JavaScript-koden du behöver lägga till; vi diskuterar den precis efter kodblocket.

// 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();
});

Låt oss bryta ner koden!

  • Ställ in ordspårning
    • Genom att använda Math.floor och Math.random kan vi slumpmässigt välja ett citat från quotes-arrayen
    • Vi konverterar quote till en array av words så att vi kan spåra det ord som spelaren för närvarande skriver
    • wordIndex sätts till 0, eftersom spelaren börjar med det första ordet
  • Ställ in användargränssnittet
    • Skapa en array av spanWords, som innehåller varje ord inuti ett span-element
      • Detta gör att vi kan markera ordet på skärmen
    • join arrayen för att skapa en sträng som vi kan använda för att uppdatera innerHTMLquoteElement
      • Detta visar citatet för spelaren
    • Ställ in className för det första span-elementet till highlight för att markera det som gult
    • Rensa messageElement genom att ställa in innerText till ''
  • Ställ in textrutan
    • Rensa det aktuella valuetypedValueElement
    • Ställ in focustypedValueElement
  • Starta timern genom att anropa getTime

Lägg till skrivlogik

När spelaren skriver kommer en input-händelse att utlösas. Denna händelselyssnare kommer att kontrollera att spelaren skriver ordet korrekt och hantera spelets aktuella status. Återgå till script.js och lägg till följande kod i slutet. Vi kommer att bryta ner den efteråt.

// 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';
  }
});

Låt oss bryta ner koden! Vi börjar med att hämta det aktuella ordet och värdet som spelaren hittills har skrivit. Sedan har vi en logik där vi kontrollerar om citatet är klart, ordet är klart, ordet är korrekt eller (slutligen) om det finns ett fel.

  • Citatet är klart, vilket indikeras av att typedValue är lika med currentWord och wordIndex är lika med ett mindre än length av words
    • Beräkna elapsedTime genom att subtrahera startTime från den aktuella tiden
    • Dividera elapsedTime med 1 000 för att konvertera från millisekunder till sekunder
    • Visa ett framgångsmeddelande
  • Ordet är klart, vilket indikeras av att typedValue slutar med ett mellanslag (slutet av ett ord) och typedValue är lika med currentWord
    • Ställ in valuetypedElement till '' för att tillåta nästa ord att skrivas
    • Öka wordIndex för att gå vidare till nästa ord
    • Loop genom alla childNodes av quoteElement för att ställa in className till '' för att återgå till standardvisning
    • Ställ in className för det aktuella ordet till highlight för att markera det som nästa ord att skriva
  • Ordet är för närvarande korrekt skrivet (men inte klart), vilket indikeras av att currentWord börjar med typedValue
    • Säkerställ att typedValueElement visas som standard genom att rensa className
  • Om vi har kommit så här långt har vi ett fel
    • Ställ in classNametypedValueElement till error

Testa din applikation

Du har kommit till slutet! Det sista steget är att säkerställa att vår applikation fungerar. Testa den! Oroa dig inte om det finns fel; alla utvecklare har fel. Undersök meddelandena och felsök vid behov.

Klicka på start och börja skriva! Det bör se ut ungefär som animationen vi såg tidigare.

Animation av spelet i aktion


🚀 Utmaning

Lägg till mer funktionalitet

  • Inaktivera input-händelselyssnaren när spelet är klart och aktivera den igen när knappen klickas
  • Inaktivera textrutan när spelaren slutför citatet
  • Visa en modal dialogruta med framgångsmeddelandet
  • Spara höga poäng med localStorage

Quiz efter föreläsningen

Quiz efter föreläsningen

Granskning & Självstudier

Läs om alla tillgängliga händelser för utvecklare via webbläsaren och fundera på scenarier där du skulle använda var och en.

Uppgift

Skapa ett nytt tangentbordsspel


Ansvarsfriskrivning:
Detta dokument har översatts med hjälp av AI-översättningstjänsten Co-op Translator. Även om vi strävar efter noggrannhet, bör det noteras att automatiserade översättningar kan innehålla fel eller brister. Det ursprungliga dokumentet på dess originalspråk bör betraktas som den auktoritativa källan. För kritisk information rekommenderas professionell mänsklig översättning. Vi ansvarar inte för eventuella missförstånd eller feltolkningar som kan uppstå vid användning av denna översättning.