Free Whack-a-Mole Game Source Code in HTML, CSS & JavaScript

This is a free Whack-a-Mole Game source code develop with HTML, CSS and JavaScript. Learn how to create, customize and run a simple browser game.

If you are looking for a simple JavaScript game project to practice your web development skills, this Whack-a-Mole game is a good place to start.

The game is built using HTML, CSS, and JavaScript. The idea is simple: a mole appears in different holes, and the player has to click it as quickly as possible to increase the score.

You do not need any external library or framework to run this game. Everything is included in one HTML file, so you can easily download, edit, and customize the source code for your own project.

What Is a Whack-a-Mole Game?

Whack-a-Mole is a quick reaction game. Several holes are displayed on the screen, and a mole randomly appears in one of them.

The player needs to click the mole before it moves to another hole. Every successful click increases the score.

This type of game is also a useful beginner project because it teaches some important JavaScript concepts, including:

  • Random number generation
  • DOM manipulation
  • Event handling
  • Timers
  • Game score management
  • Game state
  • Basic animations

Features of This Game

This free Whack-a-Mole game includes:

  • Simple and clean game interface
  • Random mole positions
  • Score counter
  • Countdown timer
  • Start Game button
  • Game over message
  • Mouse and touch support
  • Responsive design
  • No external libraries
  • Single HTML file
  • Easy-to-customize source code

Free Whack-a-Mole Game Source Code

The complete source code is provided below. You can copy it into a new HTML file and open it directly in your browser.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Whack-a-Mole Game</title>

    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: Arial, sans-serif;
            background: linear-gradient(135deg, #172554, #312e81);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
            color: white;
        }

        .game-container {
            width: 100%;
            max-width: 600px;
            text-align: center;
        }

        h1 {
            margin-bottom: 10px;
            font-size: 38px;
        }

        .subtitle {
            margin-bottom: 20px;
            color: #dbeafe;
        }

        .info {
            display: flex;
            justify-content: space-between;
            gap: 10px;
            margin-bottom: 20px;
        }

        .info-box {
            flex: 1;
            background: rgba(255, 255, 255, 0.12);
            padding: 12px;
            border-radius: 10px;
            font-size: 18px;
        }

        .game-board {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 14px;
            background: rgba(0, 0, 0, 0.2);
            padding: 18px;
            border-radius: 18px;
        }

        .hole {
            height: 120px;
            background: #111827;
            border-radius: 50%;
            position: relative;
            overflow: hidden;
            cursor: pointer;
            border: 4px solid #475569;
            display: flex;
            justify-content: center;
            align-items: flex-end;
        }

        .mole {
            width: 75px;
            height: 75px;
            background: #92400e;
            border-radius: 50%;
            position: absolute;
            bottom: -80px;
            transition: bottom 0.15s ease;
        }

        .mole::before,
        .mole::after {
            content: "";
            position: absolute;
            width: 10px;
            height: 10px;
            background: white;
            border-radius: 50%;
            top: 22px;
        }

        .mole::before {
            left: 20px;
        }

        .mole::after {
            right: 20px;
        }

        .mole.active {
            bottom: 8px;
        }

        .start-btn {
            margin-top: 22px;
            padding: 13px 28px;
            border: none;
            border-radius: 10px;
            background: #22c55e;
            color: white;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
        }

        .start-btn:hover {
            background: #16a34a;
        }

        .message {
            margin-top: 15px;
            min-height: 24px;
            font-weight: bold;
        }

        @media (max-width: 500px) {
            h1 {
                font-size: 30px;
            }

            .hole {
                height: 95px;
            }

            .mole {
                width: 60px;
                height: 60px;
            }

            .game-board {
                gap: 9px;
                padding: 12px;
            }
        }
    </style>
</head>

<body>

<div class="game-container">

    <h1>Whack-a-Mole</h1>

    <p class="subtitle">
        Click the mole as quickly as you can!
    </p>

    <div class="info">
        <div class="info-box">
            Score: <span id="score">0</span>
        </div>

        <div class="info-box">
            Time: <span id="time">30</span>s
        </div>
    </div>

    <div class="game-board">

        <div class="hole">
            <div class="mole"></div>
        </div>

        <div class="hole">
            <div class="mole"></div>
        </div>

        <div class="hole">
            <div class="mole"></div>
        </div>

        <div class="hole">
            <div class="mole"></div>
        </div>

        <div class="hole">
            <div class="mole"></div>
        </div>

        <div class="hole">
            <div class="mole"></div>
        </div>

        <div class="hole">
            <div class="mole"></div>
        </div>

        <div class="hole">
            <div class="mole"></div>
        </div>

        <div class="hole">
            <div class="mole"></div>
        </div>

    </div>

    <button class="start-btn" id="startBtn">
        Start Game
    </button>

    <div class="message" id="message"></div>

</div>

<script>
    const holes = document.querySelectorAll(".hole");
    const moles = document.querySelectorAll(".mole");

    const scoreDisplay = document.getElementById("score");
    const timeDisplay = document.getElementById("time");
    const startBtn = document.getElementById("startBtn");
    const message = document.getElementById("message");

    let score = 0;
    let timeLeft = 30;
    let gameRunning = false;

    let moleTimer;
    let countdownTimer;

    function showMole() {
        if (!gameRunning) return;

        moles.forEach(mole => {
            mole.classList.remove("active");
        });

        const randomIndex = Math.floor(Math.random() * moles.length);

        moles[randomIndex].classList.add("active");
    }

    function startGame() {
        if (gameRunning) return;

        score = 0;
        timeLeft = 30;
        gameRunning = true;

        scoreDisplay.textContent = score;
        timeDisplay.textContent = timeLeft;

        message.textContent = "";
        startBtn.textContent = "Game Running...";

        showMole();

        moleTimer = setInterval(showMole, 700);

        countdownTimer = setInterval(() => {

            timeLeft--;

            timeDisplay.textContent = timeLeft;

            if (timeLeft <= 0) {
                endGame();
            }

        }, 1000);
    }

    function endGame() {
        gameRunning = false;

        clearInterval(moleTimer);
        clearInterval(countdownTimer);

        moles.forEach(mole => {
            mole.classList.remove("active");
        });

        startBtn.textContent = "Start Again";

        message.textContent =
            "Game Over! Your final score is " + score + ".";
    }

    moles.forEach(mole => {

        mole.addEventListener("click", () => {

            if (!gameRunning) return;

            if (mole.classList.contains("active")) {

                score++;

                scoreDisplay.textContent = score;

                mole.classList.remove("active");
            }

        });

    });

    startBtn.addEventListener("click", startGame);
</script>

</body>
</html>

How to Run the Game

Running this game is very easy.

Step 1: Create an HTML File

Open a code editor such as VS Code, Notepad, or any other HTML editor.

Create a new file and name it:

index.html

Step 2: Add the Code

Copy the complete Whack-a-Mole source code above and paste it into the index.html file.

Step 3: Open It in Your Browser

Save the file and open it with Chrome, Edge, Firefox, or another modern browser.

How the Game Works

The game uses JavaScript to control the mole, score, and timer.

First, JavaScript selects all the mole elements from the HTML page.

When the player presses the Start Game button, the score is reset to zero and the timer starts counting down from 30 seconds.

Every 700 milliseconds, JavaScript chooses a random mole and displays it.

When the player clicks the active mole, one point is added to the score.

When the timer reaches zero, the game stops and the final score is displayed.

How to Customize the Game

One of the useful things about this project is that you can easily change the design and gameplay.

Change Game Time

The game currently starts with 30 seconds.

You can change:

let timeLeft = 30;

For example, change it to:

let timeLeft = 60;

Now the player will have 60 seconds.

Make the Mole Appear Faster

The mole currently changes every 700 milliseconds.

This line controls the speed:

moleTimer = setInterval(showMole, 700);

You can make the game faster by using:

moleTimer = setInterval(showMole, 500);

Change the Background

You can change the game background from the CSS:

body {
    background: linear-gradient(135deg, #172554, #312e81);
}

You can replace these colors with your own preferred colors.

Add More Holes

You can add more hole elements to the game board.

For example:

<div class="hole">
    <div class="mole"></div>
</div>

Adding more holes can make the game more challenging.

Mobile Friendly Design

The game is also designed to work on smaller screens.

The responsive CSS reduces the size of the game board and moles on mobile devices.

Because the game uses normal click events, it can also work with touch interaction on many modern mobile browsers.

You can further improve the mobile experience by adding touch-specific controls or sound effects.

Ideas for Future Improvements

Once you understand the basic code, you can add more features to make the game more interesting.

Some ideas include:

  • Add sound effects
  • Add different mole characters
  • Add difficulty levels
  • Add a high-score system
  • Add a leaderboard
  • Add bonus points
  • Add special golden moles
  • Add background music
  • Add game animations
  • Add a pause button
  • Save the highest score using localStorage

These improvements can turn this simple project into a much more complete HTML5 browser game.

Why This Is a Good JavaScript Project

A Whack-a-Mole game may look simple, but it gives beginners practical experience with several important programming concepts.

You learn how to select HTML elements, respond to user clicks, generate random numbers, create timers, update content dynamically, and control the state of a game.

These are the same basic concepts that are used in many larger browser games.

You can use the source code for learning, experimentation, and your own personal projects. Change the colors, add sounds, create new characters, or add different difficulty levels to make the game your own.

If you are building a collection of HTML5 game projects, this is another useful game to add alongside Snake, Tic Tac Toe, Memory Card, Rock Paper Scissors, Car Racing, and Breakout.