Starting & Ending The Game

We continue in the same project folder throughout this section.

What we will be doing

The Objective:

To create the start and end of game functions to begin our orders displaying, clear an existing selected orders, and also to control the UI.

play and stop buttons

Steps:

  1. Create startOfGame() and endOfGame() functions.
  2. Call these by adding an event listener (click) to the #startBtn & #endBtn HTML elements.
  3. Create a gameStarted Boolean variable. Set to true in startOfGame() and false in endOfGame().
  4. Return from startOfGame() if gameStarted is true.
  5. All orders have a class of "order_wrapper". In startOfGame(), clear these to remove any existing orders.
  6. Move the createOrdersList() function call to inside of the startOfGame() function.
  7. startOfGame() function - show #endBtn / hide #startBtn (using style property).
  8. endOfGame() function - hide #endBtn / show #startBtn (using style property).
  9. Hide #endBtn when game first loads.

Above is a list of steps to try things yourself. What we are aiming to cover is creating two functions, one to start the game and one to end it. These are called from the HTML buttons we already have.

The idea behind them is to clean up the user interface to only show the correct things, such as only showing the end game button when the game is running, to use the start button to begin displaying the orders and so on.

These functions will be useful later when we add things like stats and timers to the game. As ever, either try these yourself, or we will cover these now if you want to follow along.

Creating and calling the functions

First, create the functions at the bottom of the script:

// 1. Create functions
function startOfGame() {}
function endOfGame() {}

// 2. Add event listeners to buttons, calling the above functions:
document.querySelector('#startBtn').addEventListener('click', startOfGame);
document.querySelector('#endBtn').addEventListener('click', endOfGame);

Tracking if the game is running

The next step was to create a gameStarted variable:

// …
let pizzasCompleteForOrder = 0;
// add variable:
let gameStarted = false;

This variable will then update from the two functions:

function startOfGame() {
  gameStarted = true;
}
function endOfGame() {
  gameStarted = false;
}

Knowing if the game is already running will be useful. This startOfGame function will be doing some clean-up work such as removing existing orders, and we don’t want the user to accidentally run this mid-game, so we can return out of the function if gameStarted is true:

function startOfGame() {
  if (gameStarted) {
    return;
  }
  gameStarted = true;
}

We will also hide the start game button soon, but there is no harm in being extra safe here.

Clearing previous orders

After this we remove any orders from the previous game:

function startOfGame() {
  if (gameStarted) {
    return;
  }
  gameStarted = true;

  // 1. select all orders by class name:
  const orders = document.getElementsByClassName('order_wrapper');

  // 2. loop through and remove all
  // Array object has a from method to create an array from things like
  // htmlCollections (which we have here)
  // This means we can use array methods such as forEach
  Array.from(orders).forEach(function(order) {
    order.remove();
  });
}

Creating orders when the game begins

Locate the following line in your index.js file:

createOrdersList();

This createOrdersList function creates the orders. It would make sense to only call this function when the game has started, so we can move this down into the startOfGame function:

function startOfGame() {
  if (gameStarted) {
    return;
  }
  gameStarted = true;
  const orders = document.getElementsByClassName('order_wrapper');
  Array.from(orders).forEach(function(order) {
    order.remove();
  });
  createOrdersList();
}

Show and hide the game buttons

The game start and game end buttons only need to display at certain time. This can be toggled with the style property:

function startOfGame() {
  if (gameStarted) {
    return;
  }
  // hide start button, display end button:
  document.querySelector('#startBtn').style.display = 'none';
  document.querySelector('#endBtn').style.display = 'inline';

  gameStarted = true;
  const orders = document.getElementsByClassName('order_wrapper');
  Array.from(orders).forEach(function(order) {
    order.remove();
  });
  createOrdersList();
}

function endOfGame() {
  gameStarted = false;
  // hide end button, display start button:
  document.querySelector('#endBtn').style.display = 'none';
  document.querySelector('#startBtn').style.display = 'inline';
}

When the game first loads, we don’t need to show the end button on the screen. Add the following code to hide this button near the variables:

let gameStarted = false;
// hide the end button using the display property:
document.querySelector('#endBtn').style.display = 'none';

This is the end of this section! We will add the this game in the following section where we discover JavaScript Math, Date, and Timers!

fireworks image

Completed code after this lesson

If needed, here is the completed code we added to the starter file:

let oven = [];
const ovenCapacity = 6;
let pizzasCompleteForOrder = 0;
let gameStarted = false;
document.querySelector("#endBtn").style.display = "none";

function buildElement(elementName, elementContent) {
    const element = document.createElement(elementName);
    const content = document.createTextNode(elementContent);
    element.appendChild(content);
    return element;
}

function createListOfPizzas(pizzas) {
    const pizzaList = document.createElement("ul");
    pizzas.forEach(function (pizza) {
        const orderQuantityEl = buildElement("span", `${pizza.quantity} - `);
        const pizzaNameElement = buildElement("span", pizza.name);
        pizzaNameElement.classList.add("pizza_name");
        const pizzaItem = document.createElement("li");
        pizzaItem.append(orderQuantityEl, pizzaNameElement);
        pizzaList.appendChild(pizzaItem);
    });
    return pizzaList;
}

function createSingleOrder(order) {
    const orderWrapper = document.createElement("div");
    orderWrapper.className = "order_wrapper";
    orderWrapper.addEventListener("click", selectCurrentOrder);
    const orderNumberEl = buildElement("h4", `Order: ${order.id}`);
    orderWrapper.appendChild(orderNumberEl);
    const pizzaList = createListOfPizzas(order.pizzas);
    orderWrapper.appendChild(pizzaList);
    return orderWrapper;
}

function createOrdersList() {
    orders.forEach(function (order) {
        const singleOrder = createSingleOrder(order);
        document.querySelector("#orders").appendChild(singleOrder);
    });
}

function selectCurrentOrder(e) {
    const pizzas = document.querySelectorAll(".pizza_name");
    pizzas.forEach(function (pizza) {
        pizza.addEventListener("click", setCurrentPizza);
    });

    if (document.querySelector("#working_on").children.length > 1) {
        return;
    }
    let element = e.target;
    const orderWrapper = element.closest(".order_wrapper");
    if (orderWrapper !== null) {
        orderWrapper.removeEventListener("click", selectCurrentOrder);
        const orderDiv = document.querySelector("#working_on");
        orderDiv.appendChild(orderWrapper);
    }
}

function setCurrentPizza(e) {
    const pizzaName = e.target.innerText;
    document.querySelector("#current_pizza").innerText = pizzaName;
    displayMethod(pizzaName);
}

function displayMethod(pizzaName) {
    document.querySelector("#pizza_name").innerText = pizzaName;
    const selectedPizza = pizzas.find((pizza) => pizza.name === pizzaName);
    const methodSteps = selectedPizza.method.split(".");
    document.querySelector("#pizza_method").innerHTML = "";
    methodSteps.forEach(function (method) {
        const element = buildElement("li", method);
        document.querySelector("#pizza_method").appendChild(element);
    });
}

function addToOven() {
    pizzasCompleteForOrder++;
    const pizzaName = document.querySelector("#current_pizza").innerText;
    if (pizzaName) {
        const pizzaForOven = {
            name: pizzaName,
            timeAdded: "5/5/28",
        };
        oven.push(pizzaForOven);
        displayOvenItems();
    }
}

document.querySelector("#addToOven").addEventListener("click", addToOven);

function displayOvenItems() {
    document.querySelector("#oven").innerHTML = "";
    oven.forEach(function (pizza) {
        const pizzaDiv = document.createElement("div");
        pizzaDiv.className = "pizza_div";
        const image = document.createElement("img");
        image.src = "pizza.svg";
        const pizzaName = buildElement("p", `(${pizza.name})`);
        pizzaDiv.append(image, pizzaName);
        document.querySelector("#oven").appendChild(pizzaDiv);
    });
}

function startOfGame() {
    if (gameStarted) {
        return;
    }
    document.querySelector("#startBtn").style.display = "none";
    document.querySelector("#endBtn").style.display = "inline";

    gameStarted = true;
    const orders = document.getElementsByClassName("order_wrapper");
    Array.from(orders).forEach(function (order) {
        order.remove();
    });
    createOrdersList();
}

function endOfGame() {
    gameStarted = false;
    document.querySelector("#endBtn").style.display = "none";
    document.querySelector("#startBtn").style.display = "inline";
}
document.querySelector("#startBtn").addEventListener("click", startOfGame);
document.querySelector("#endBtn").addEventListener("click", endOfGame);