DEV Community

Cover image for Build Your First Typing Game with JavaScript - Part 2
Confidence Nwalozie
Confidence Nwalozie

Posted on

Build Your First Typing Game with JavaScript - Part 2

This is a continuation of the Build your first typing game with Javascript series.

In the first part of the tutorial, we laid out the game's functional requirements and structured the webpage to display a portion of its interactive content. However, the game is still unplayable at this stage.

We will proceed by delegating the game's functional components to different parts that handle fractions of the game's logic. These parts are generally described as modules.

Concept of Modules

A module is a self-contained unit of code that can be imported and used in other files within a project. These code units could feature functions, variables, classes, or objects that perform a specific task or set of related tasks.

Think of modules like division of labor in an event planning process.

Each department is responsible for executing its assigned duties, but all departments contribute to making the event successful.

Similarly, modules focus on specific functionalities.

Once a module is created, you can "invite" or import it into other project parts whenever you need to handle that same functionality again.

This is a crucial concept in web development because it allows for:

  • Better organization: As code is broken into manageable pieces.

  • Reliable testing: Individual modules can be tested in isolation to ensure their functionality before integrating with other modules.

  • Ease of maintenance: You can update or debug specific modules without affecting the rest of the project.

  • Code reusability: Modules can be reused in different parts of a project, or even across entirely different projects as libraries.

Creating a Module

Now that you have been introduced to the concept of modules, let's get the ball rolling on how to create a module.

Quotes Module

In the root directory, create a new folder named modules. Within this folder, add a new file quotes.js.

We need 20 random quotes for the module content.

Draft quotes from your favorite philosophers (eg. Professor Dumbledore, Sherlock Holmes) or prompt a Large Language Model like ChatGPT to generate them within a specific sentence length limit.

Use the following prompt (without the quotation):

'Generate 20 Quotes from *philosopher_name* with a sentence range of 10 - 12 words.
 Present the quotes in a Javascript string array format.'
Enter fullscreen mode Exit fullscreen mode

Or use the sample response below. Copy it into the newly created file and ensure the variable name is defined as quotes.

//./modules/quotes.js
export const quotes = [  
    "Happiness can be found even in the darkest of times.",  
    "Words are, in my not-so-humble opinion, our most inexhaustible source.",  
    "It matters not what someone is born, but what they grow to be.",  
    "It is our choices, far more than our abilities, that show who we are.",  
    "You must be the change you wish to see in the world.",  
    "The truth is a wonderful yet terrible thing, and should therefore be treated with caution.",  
    "Do not pity the dead, Harry. Pity the living.",  
    "The greatest magic is the magic of love and friendship.",  
    "We are only as strong as we are united, as weak as we are divided.",  
    "You will find the world is full of unusual things.",  
    "The best of us must sometimes eat our words.",  
    "It is the quality of one's convictions that determines success.",  
    "Perhaps those who are best suited to power are those who never sought it.",  
    "To have been loved so deeply will give us some protection.",  
    "A good man’s life should be measured by his kindness.",  
    "Sometimes you must choose between love and duty, each has its cost.",  
    "The future is unwritten. It is ours to shape.",  
    "The long term is the key to understanding our short-term actions.",  
    "Fear of a name increases fear of the thing itself.",  
    "Even the smallest person can change the course of the future.",  
    "In dreams, we enter a world that is entirely our own."  
];  
Enter fullscreen mode Exit fullscreen mode

Notice the inclusion of an export function before the variable declaration? This makes the array accessible by another file in the project.

Note: The concept of modules is based on the principle of dependability. A file component qualifies as a module only when it has shared its functionality and provided value to another component.

Awesome. Now we have a module holding an array of quotes that will be utilized in the game.

Windows Storage Property

Recall that one of the expectations for our game is to track and (possibly) retain typing records after each play session. These typing records will typically be stored on the web browser in a compartment known as Local Storage.

An alternative location is the Windows Session Storage, which is similar to local storage but only available for the duration of a user's current browsing session.

We would use the Local storage option to store the player's highscores so that the records persist even after the user exits the page.

Highscores Module

Create a new file named highscores.js in the modules folder.

In this file, we define four sets of functions to store, fetch, display, discard, and erase typing records as needed within the game.

N/B: A score refers to the time it takes a player to finish typing a quote and a list of scores accumulates to form typing score records.

We want to store at most 10 scores per time.

  1. This saveHighScore(param*) function takes a score parameter and does four things. It :

    • Adds the score to the list of highscores in local storage.
    • Ranks all highscores (including the newly added score) in ascending order - quickest to slowest.
    • Stores only the top 10 scores after sorting.
    • Returns a Boolean value that communicates whether the new score was retained or not. (True or False).
    //./modules/highscores.js
    export function saveHighScore(score) {
        let highScores = getHighScores(); // Gets all highscores in local storage
        highScores.push(score); //Adds the new score to the list of highscores
        highScores.sort((a, b) => a - b); // Sorts scores in ascending order
        if (highScores.length > 10) {
            highScores = highScores.slice(0, 10); // Keeps only the top 10 scores
        }
        localStorage.setItem('highScores', JSON.stringify(highScores)); //saves top 10 scores to local storage
        return highScores.includes(score); // Returns true if the current score is in the top 10
    }
    
  2. The getHighScores() function retrieves an array of highscores in JSON format from the browser's local storage.

    Notice the use of ternary operators (? and :). Ternary operators serve as a concise alternative to traditional if-else statements.

    export function getHighScores() {
        const highScores = localStorage.getItem('highScores');
        /* Checks if there are any high scores stored.
        Parses the JSON string into an array if true; else, returns an empty array.*/
        return highScores ? JSON.parse(highScores) : [];  
    }
    
  3. We'll use another function displayHighScores() to handle how scores are displayed after each game session.

    export function displayHighScores() {
      const highScores = getHighScores(); // Gets all highscores in local storage
    
      // Formats the highscores as a numbered list
      const formattedScores = highScores
      .map((score, index) => `${index + 1}. ${score} seconds`)
      .join('\n');
    
      // Returns the formatted scores as a single string element
      return formattedScores;
    }
    
  4. Finally, the clearHighScore() function erases all typing records from the browser's local storage.

    export function clearHighScores() {
      localStorage.removeItem('highScores');  // clear all high scores from local storage
    }
    

Note: These are self-contained functions and do not need to be arranged chronologically in the highscores.js module.

Excellent!

Now that we have both the quotes and highscores modules set up, we have a solid base to get the game fully functional.

The game's main logic consists of triggers that signal the browser what to do and when to do what as players interact with the web page elements.

For example, in this demo from part one, you can see that the page elements change when the start button is clicked. Some hidden elements become visible, while those initially displayed disappear as the game moves to its second phase. This interaction is enabled by the click event trigger.

These triggers are an integral part of Event Listeners and we will explore the concept, its syntax, and implementation in the next and final part of the tutorial.

Top comments (0)