Lab 4: Building a Point-and-Click Game


General Description

Over the next two labs, you will transition from displaying static cards to building a simple interactive game.

You will get introduced to the concepts of functions, conditional logic, and reactivity to handle changes in the user interface and validate user choices, respectively.

Learning Objectives

  1. Manage application reactivity and state using JavaScript functions.
  2. Implement conditional logic (if/else) to create user conditions and toggles.

Table of Contents


  1. Pre-requisite: Setup Your Project
  2. Choose a Theme
  3. Create Reference Card
  4. Create Gameplay Card
  5. Validate and Show Result
  6. Styling the Game Environment
  7. Optional Challenge: Expand Your Game

Pre-requisite: Setup Your Project


  1. Create a new folder for this lab.
  2. Inside your new folder create the app.js and index.html files with their starter/boilerplate code. Refer to Lab 2, section "Setup Starter Vuetify Code" to complete this step.
    • Finally, in the section const { createApp} = Vue in app.js, import the ref command which we will use in the next steps below:
    • 
      const { createApp, ref } = Vue;
              

Choose a Theme


Point-and-click adventure games are those where the player controls their character through a computer mouse. Often, these games come down to collecting items for the character's inventory, and figuring when is the right time to use that item; the player would need to use clues from the visual elements of the game, descriptions of the various items, and dialogue from other characters to figure this out. Read more.

In this lab, the player will consult a reference card to learn a plant's needs and then click the correct actions in the right order to help it grow. You can use this same theme or choose a different one of your own, as long as it follows the same logical steps.

  1. Brainstorm a theme for your interactive game. While this lab uses "Plant Care" as an example, you are encouraged to adapt the theme to any subject (e.g., Space Repair, Cooking, or Pet Care).
  2. Identify one primary subject and 3-4 action verbs that the user must perform in a specific order to succeed (e.g., "Pour," "Mix," "Bake"). See more examples in the table below.
  3. Theme Subject Action Verb 1 Action Verb 2 Action Verb 3
    Plant Care Lily Water Prune Fertilize
    Bakery Cake Whisk Knead Bake
    Space Repair Satellite Calibrate Recharge Deploy
    Coffee Shop Latte Grind Steam Pour

Create Reference Card


The "reference card" will act as the manual for your game. It will tell the player the sequence of actions they have to follow to succeed.

Describe the Subject and Action Verbs with Variables

  1. In app.js, define your subject's name and the action verbs using variables. Refer to Lab 2, section "Describe Your Theme With Variables", to complete this step.
  2. In index.html, add a card to display your variables using {{ }} to pull the data from app.js. Refer to Lab 2, section "Display Your Theme Data in a Card ", to complete this step.

Adding Toggle Functionality to Open/Close the Reference Card


In this step you will create a reactive variable and a function to toggle between true and false to open or close your reference card. You will then connect this function to a button using v-btn.

  1. Create a new variable with a name like showReferenceCard and an initial value of false.
  2. 
    const showReferenceCard = false
        
  3. Inside your v-card from the previous step, add the command v-if and the name of your variable as the value. If you refresh the page, you should see your card disappear.
  4. 
        <v-card v-if="showReferenceCard">
            
    💡 Coding Concept: The command v-if is used for conditional rendering. When showPlantCard is true, Vuetify adds the card to the page; when it is false, Vuetify removes it.
  5. Now, let's define a function to toggle showReferenceCard between false and true to allow the card to open or close. In app.js, create an empty function with a name like toggleOpenCloseReferenceCard. Follow the example below:
  6. 
    function toggleOpenCloseReferenceCard() {}
            
    💡 Coding Concept: A function is a resusable code block designed to perform a particular task.
  7. Inside the function, add an if-else statement to alternate from false to true each time the function is executed/triggered. Follow the example below:
  8. 
    function toggleOpenCloseReferenceCard() {
        if (showReferenceCard.value == false) {showReferenceCard.value = true} 
        else {showReferenceCard.value = false}
    }
            
    💡 Coding Concept: An if-else statement allows to run different code for different conditions. The syntax is the following:
    
    if (condition) {// code to execute if the condition is true} 
    else {// code to execute if the condition is false}
            
  9. To trigger the function, add a button using v-btn and the command @click with the name of your function as the value.
  10. 
    <v-btn @click="toggleOpenCloseReferenceCard">Reference Card</v-btn>
            
    💡 Coding Concept: @click allows to trigger a function with a button.
  11. Update your showReferenceCard variable value by adding the keyword ref. This makes the variable reactive, ensuring that when you click the toggle button, the interface updates automatically.
  12. 
    const showReferenceCard = ref(false); 
        
    💡 Coding Concept: When creating apps, there is a concept called reactivity, where values like the one inside your variable showReferenceCard can change behind the scenes when the user interacts with it. ref() is used to create a reactive reference to any value including strings, numbers, booleans, objects, and arrays.
  13. Now, save your changes, refresh your page in the browser, and click the button to see your card open and close.

Create Gameplay Card


In this step, you'll build the gameplay card with action buttons and a function to save the user's choices.

Create Variables to Save the User Actions

  1. In app.js, create the reactive variables to save the user's choices. Since no actions have been taken yet, set these variables to null as a placeholder until the user starts clicking the buttons. Follow the example below:

const userAction1 = ref(null)
const userAction2 = ref(null)
const userAction3 = ref(null)
      
💡 Coding Concept:A null value denotes the absence of a value or serves as a placeholder for a value that isn't present but might be present in the future.

Create a Function to Record the User Actions

Now, define a function that records each click. When a player selects an action like "water" or "prune", the function will save that choice into your variables from the previous step.

  1. Define an empty function with a name like recordUserAction.
  2. 
    function recordUserAction() {}
            
  3. Add a parameter to the function. Name the parameter something like action.
  4. 
    function recordUserAction(action) {}
            
    💡 Coding Concept: Parameters allow you to pass or send values to a function. Parameters are listed inside the parentheses in the function definition.
  5. Inside the function, add an if-else statement to check your variables in order. If a variable is empty (null), the function will fill it with the clicked action.
  6. 
    function recordUserAction(action) {
        if (userAction1.value === null) {
            userAction1.value = action;
        } else if (userAction2.value === null) {
            userAction2.value = action;
        } else if (userAction3.value === null) {
            userAction3.value = action;
        }
    }     
    
    💡 Logic Check: The else if is important in this function, since it will tell the computer to stop looking once it finds the first empty slot (variable).

Create Card with Action Buttons

Now, let's create the card containing the action buttons. These buttons will trigger the recording function you created in the previous step.

  1. In index.html, create a new card. Use your subject’s name as the title, then add a button for each action. See the example below:
  2. 
    <v-card>
        <v-card-title>{{ plantName }}</v-card-title>
        <v-btn>water</v-btn>
        <v-btn>prune</v-btn>
        <v-btn>fertilize</v-btn>
    </v-card>
    
  3. Add the @click command to each button using your recordUserAction function. Be sure to pass the action name inside single quotes so the function knows which button was clicked. Follow the example below:
  4. 
    <v-card>
        <v-card-title>{{ plantName }}</v-card-title>
        <v-btn @click="recordUserAction('water')">water</v-btn>
        <v-btn @click="recordUserAction('prune')">prune</v-btn>
        <v-btn @click="recordUserAction('fertilize')">fertilize</v-btn>
    </v-card>
    

Adding Toggle Functionality to Open/Close the Gameplay Card

  1. Following step 3.2 above, create a new variable and function that uses an if-else statement to toggle between true and false. Then, connect this variable and function to the card and the new button using v-if and @click, respectively.

Validate and Show Result


To tell the player if they succeeded, we need a variable to store the 'success/fail' message and a function that compares the user actions to the actions in the reference card.

  1. In app.js, create a new variable called result with a null value.
  2. 
    const result = ref(null)
     
  3. Create a function with a name like validateResult. This function will use an if-else statement to check if all three user actions match the correct references.
  4.  
    function validateResult() {
         if (userAction1.value === actionReference1 && 
             userAction2.value === actionReference2 && 
             userAction3.value === actionReference3) {
        result.value = "Your plant is thriving!";
    } else {
        result.value = "Your plant withered.";
    }
    } 
    💡 Logic Symbols:
    • === checks for equality. It checks if the value on the left is exactly the same as the value on the right.
    • && allows us to check multiple conditions at once. The whole statement is only true if every part is true.
  5. Now that we have the validate-result logic, let's visualize it. Inside the gameplay card, add a <v-card-text> to display the result variable to the player.
  6.  
    <v-card-text> 
      {{ result }} 
    </v-card-text> 
    
  7. Finally, inside your gameplay card, add a v-card-actions and a v-btn to trigger the validation function using the @click command.
  8.  
    <v-card-actions> 
      <v-btn @click="validateResult">Validate Result</v-btn> 
    </v-card-actions>
    

Styling the Game Environment


In this step, you will transform your user interface into a game world using a background image, positioning your buttons, and styling your cards.

Add a Background Image

  1. Find an image online related to your theme and subjects. Save your image in your lab folder. For this lab, I am using a flower shop image from https://www.freepik.com/, since the theme is "Plant Care" and the subjects are plants and flowers.
  2. Create a variable to store your image and <v-img> to display it. Refer to Lab 2, section "Display Your Theme Data in a Card" to complete this step.

Positioning the Buttons and Cards

Last lab, we used Vuetify's 12-column grid, which allows organizing elements in a structured grid. This time, however, we need the buttons to layer in different places on top of our image. To achieve this, we will use absolute positioning, a system that is based on screen coordinates.

  1. In app.js, add the following helper function that will allow you to locate the screen coordinates:
  2.  
    function findCoordinates(event) {
        const windowWidth = window.innerWidth;
        const windowHeight = window.innerHeight;
        const xPercent = (event.clientX / windowWidth) * 100;
        const yPercent = (event.clientY / windowHeight) * 100;
        console.log(`X: ${xPercent.toFixed(2)}%, Y: ${yPercent.toFixed(2)}%`);
    }
    
  3. Add this function to your v-image to trigger it using @click.
  4.  
    <v-img :src="image" @click="findCoordinates"></v-img>
                            
  5. To print the coordinates, open the browser console tools in your browser. Click the three dots on the top right, then More Tools, then Developer Tools. See video guide below:
  6. Now that you have the x and y coordinates, start by adding the command style with the value position:absolute; and z-index:1; to the reference card button you created before.
  7.  
    <v-btn style="position:absolute; z-index:1;" @click="toggleOpenCloseReferenceCard">Reference Card</v-btn>
    
    💡 Styling Concept: The z-index command specifies the stack order of an element. An element with greater stack order is always in front of an element with a lower stack order.
  8. Then, inside style add your x coordinate to the command left and your y coordinate to the command top:
  9.  
    <v-btn style="position:absolute; z-index:1; left: 12.64%; top:17.10%;" @click="toggleOpenCloseReferenceCard">Reference Card</v-btn>
    
  10. Repeat the same process with the reference card, the gameplay button, and the gameplay card.

Styling Your Cards

  1. Modify the width and color of your cards. Refer to Refer to Lab 2, section "Style the Card" to complete this step.

Optional Challenge: Expand Your Game


Try expanding your game by adding more subjects to the reference card and more gameplay cards.

Wrap Up & Saving Your Work


Congratulations! You've reached the end of this lab.

What You Achieved Today:

  • State Management: You used ref() to create "reactive" variables that allow the website to update instantly when data is changed by the user, for example, by clicking buttons.
  • Game Logic & Validation: You built a function using conditional statements (if-else) and logical operators (&&) to determine a win or loss.
  • Responsive Positioning: You used screen percentages to place elements precisely so your game works on any screen size.
Next Steps: We aren't finished with our game yet! In Part 2, you will practice adding more gameplay cards using Arrays and Loops.

Save for Next Week:

There is no formal submission today, however, please ensure your project is saved correctly in your computer and ready to use next class.