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
pointsandtimeand 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>- Something to think about
In
hit(): points=points+1; and thendocument.querySelector("#points").textContent=points; - Which command helps?
target.style.left=Math.floor(Math.random() * 341)+"px"; – the same for top with 221.
Solve it without hints to earn a ⭐ on your progress page.
Show solution🔒 Unlocks after all hints or 2 checks
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>