Shape Drop Game- Handling The Score & End of Game

Open the project folder

This lesson continues from the previous lessons starter file.

Tracking the score

Our game is functional in terms of the drag and drop, but to make it even better, we could keep track of the score, and reset the game at the end.

First let’s handle the score. At the top of the script we need a variable to store this:

// script.js
let score = 0;
// ...

In the index.html, we already have a <span> element to display the score:

<header>
  <h3>Score: <span id="score"></span> </h3>

The place to update the score will be inside of the handleDrop function, since this is where we check if the correct shape has been dropped:

function handleDrop(e) {
  if (e.target.classList.contains(selected.className)) {
    e.target.classList.remove('drop');
    selected.remove();
    // 1. increase score if correct:
    score++;
    // 2. update in the browser:
    document.querySelector('#score').innerHTML = score;
    return;
  }
  console.log('incorrect');
}

And then do the opposite if the shape is dragged into the wrong section:

function handleDrop(e) {
  if (e.target.classList.contains(selected.className)) {
    e.target.classList.remove('drop');
    selected.remove();
    score++;
    document.querySelector('#score').innerHTML = score;
    return;
  }
  // replace console log with:
  score--;
  document.querySelector('#score').innerHTML = score;
}

When we first start the score is zero, so we need to have zero set in the browser. This can be set just above our handleDrop function:

document.querySelector('#score').innerHTML = score;
function handleDrop(e) {
// …

The play again button

Now we can handle what to do at the start and end of a game. First the “play again” button needs to only show at the end of the game. Grab the button and hide it initially:

let score = 0;
let selected;
const dropzones = document.querySelectorAll('.drop');
// 1. select button
const startGameBtn = document.querySelector('button');
// 2. hide button using CSS
startGameBtn.style.display = 'none';

This will hide the button when the game first loads.

Game start and end functions

Next, create two new functions to handle what to do at the start and end of a game:

// …
function endGame() {}
function startGame() {}

function handleDrop(e) {
// ...

At the end of the game, we re-introduce the play again button so the user can re-start:

function endGame() {
  startGameBtn.style.display = 'inline';
}

To start the game, we need to reset everything back to it's original state. This includes the score, removing the play again button, and moving the shapes back into position. We could do all of this manually, or we could refresh the page to give the same effect:

function startGame() {
  // window has a location object to get the current page
  // then call the reload method:
  window.location.reload();
}

We have these functions and now we need to call them. The start game is simple, we just call it when the play again button is clicked:

// …
startGameBtn.style.display = 'none';
// add event listener:
startGameBtn.addEventListener('click', startGame);

The end game function is a little trickier. We need to check if all the shapes have been successfully removed. Over in the HTML, we have this drag-section wrapper:

<div class="drag-section">
  <div class="rectangle" draggable="true"></div>
  <div class="square" draggable="true"></div>
  <div class="pill" draggable="true"></div>
  <div class="square2" draggable="true"></div>
  <div class="oval" draggable="true"></div>
  <div class="oval2" draggable="true"></div>
  <div class="pill2" draggable="true"></div>
  <div class="circle" draggable="true"></div>
  <div class="rectangle2" draggable="true"></div>
  <div class="rectangle3" draggable="true"></div>
</div>

And we remove each one of the shapes when the user is correct. This means the game is over when this wrapper has no child elements left. Select the drag-section at the top of the handleDrop function:

function handleDrop(e) {
  console.log(document.querySelector('.drag-section'));

The childElementCount property

Elements have access to a property to find the number of child elements it contains, called childElementCount. We can see this by loggin to the console:

function handleDrop(e) {
  console.log(document.querySelector('.drag-section').childElementCount);
  // ...

Log this to the console by dropping our elements into the drop zone. You will see that the number logged is always one higher than the actual number of elements. This happens because the check happens at the top of the function before we remove the element. Meaning the game is over when this value is one.

Now we have this working, change the console log to an if statement:

function handleDrop(e) {
  if (document.querySelector('.drag-section').childElementCount === 1) {
    endGame();
  }

This will only run if the number of elements is equal to one, and then the endGame function will be called.

Finishing touch

A finishing touch is to also remove the border form the bottom section when all shapes have been removed. This is not affecting the game, but is does not look good with no content inside. And we can remove this at the end of the game:

function endGame() {
    startGameBtn.style.display = "inline";
    document.querySelector(".drag-section").style.border = "none";
}

The game is now complete!

fireworks image