Skip to content
BetaDE
Lesson 11 of 11JavaScript

JavaScript · Lesson 11 · 45 minutes

Project: click hunt in the browser

What you'll learn

  • Put an element at a random place with JavaScript
  • Make a clock count down with setInterval
  • Combine HTML, CSS and JavaScript into a finished game

Your first browser game

Now you put it all together: a game area made of HTML, colours from CSS and game rules from JavaScript. A target jumps around the area. You have 20 seconds – how often can you hit it?

Placing elements freely

With position: absolute you can put an element exactly where you want. left is the distance from the left edge, top the distance from the top. The area around it needs position: relative:

<style>
  #area { position: relative; width: 300px; height: 150px; background: #eef; }
  .dot { position: absolute; width: 20px; height: 20px; border-radius: 50%; background: crimson; }
</style>

<div id="area">
  <div class="dot" style="left: 10px; top: 10px"></div>
  <div class="dot" style="left: 140px; top: 65px"></div>
  <div class="dot" style="left: 270px; top: 120px"></div>
</div>

Random places

Math.random() gives a decimal number from 0 to just under 1. Times 341 and rounded down with Math.floor, that makes a whole number from 0 to 340. Click the button several times:

<style>
  #area { position: relative; width: 300px; height: 150px; background: #eef; }
  #dot { position: absolute; left: 140px; top: 65px; width: 20px; height: 20px; border-radius: 50%; background: crimson; }
</style>

<div id="area"><div id="dot"></div></div>
<button id="go">Somewhere else!</button>

<script>
  const dot = document.querySelector("#dot");
  document.querySelector("#go").addEventListener("click", () => {
    const x = Math.floor(Math.random() * 281);
    const y = Math.floor(Math.random() * 131);
    dot.style.left = x + "px";
    dot.style.top = y + "px";
    console.log("New place:", x, y);
  });
</script>

Why 281 and not 300? The dot is 20 wide. At left: 300px it would already be completely outside.

A clock with setInterval

setInterval(function, 1000) calls the function every second. clearInterval stops it again:

<p>Countdown: <strong id="display">5</strong></p>

<script>
  let left = 5;
  const clock = setInterval(() => {
    left = left - 1;
    document.querySelector("#display").textContent = left;
    if (left === 0) {
      clearInterval(clock);
      console.log("Go!");
    }
  }, 1000);
</script>

In the task, the clock is already finished. Only the function hit() is missing.

Keep building: Make the target a little smaller with every hit. At the end, show a big message “Game over – 17 points!” in the area. Or build a restart button that resets points and time and starts the clock again.

Your task

Your turn

Finish the click hunt. Write the function hit(). It increases points by 1, writes the number into #points and puts the target #target at a random place in the game area: left between 0 and 340, top between 0 and 220 (each with "px" after it). It's called on every click on the target – but only while there's time left.

<style>
  body { font-family: sans-serif; }
  #area { position: relative; width: 400px; height: 280px; background: #102030; border-radius: 12px; }
  #target { position: absolute; left: 170px; top: 110px; width: 60px; height: 60px;
            border: none; border-radius: 50%; background: tomato; font-size: 28px; cursor: pointer; }
</style>

<p>Points: <strong id="points">0</strong> · Time: <strong id="time">20</strong> s</p>
<div id="area"><button id="target">🎯</button></div>

<script>
  let points = 0;
  let time = 20;
  const target = document.querySelector("#target");

  function hit() {
    // Count points, show them, move the target
  }

  target.addEventListener("click", () => {
    if (time > 0) {
      hit();
    }
  });

  const clock = setInterval(() => {
    time = time - 1;
    document.querySelector("#time").textContent = time;
    if (time === 0) {
      clearInterval(clock);
      target.textContent = "🏁";
      console.log("Time's up! Points:", points);
    }
  }, 1000);
</script>

Solve it without hints to earn a ⭐ on your progress page.

Show solution

Try it yourself first – mistakes teach you the most. Here is one possible solution:

<style>
  body { font-family: sans-serif; }
  #area { position: relative; width: 400px; height: 280px; background: #102030; border-radius: 12px; }
  #target { position: absolute; left: 170px; top: 110px; width: 60px; height: 60px;
            border: none; border-radius: 50%; background: tomato; font-size: 28px; cursor: pointer; }
</style>

<p>Points: <strong id="points">0</strong> · Time: <strong id="time">20</strong> s</p>
<div id="area"><button id="target">🎯</button></div>

<script>
  let points = 0;
  let time = 20;
  const target = document.querySelector("#target");

  function hit() {
    points = points + 1;
    document.querySelector("#points").textContent = points;
    target.style.left = Math.floor(Math.random() * 341) + "px";
    target.style.top = Math.floor(Math.random() * 221) + "px";
  }

  target.addEventListener("click", () => {
    if (time > 0) {
      hit();
    }
  });

  const clock = setInterval(() => {
    time = time - 1;
    document.querySelector("#time").textContent = time;
    if (time === 0) {
      clearInterval(clock);
      target.textContent = "🏁";
      console.log("Time's up! Points:", points);
    }
  }, 1000);
</script>