Building a Web Avoiding Block Game

JavaScriptJavaScriptIntermediate
Practice Now

Introduction

In this project, we are going to build a fun and simple avoiding block game using HTML, CSS, and JavaScript. This game involves moving blocks where the player must click the black blocks to score points and avoid clicking the white blocks. Let's start building it step by step!

👀 Preview

project-building-a-web-based-block-avoidance-game

🎯 Tasks

In this project, you will learn:

  • How to design the game layout using HTML
  • How to add styling to the game using CSS
  • How to implement the basic game logic using JavaScript
  • How to initialize the game and create the initial set of blocks
  • How to implement gameplay functionality, including block click detection, game-over scenarios, block creation, and movement
  • How to finalize game scoring and speed management

🏆 Achievements

After completing this project, you will be able to:

  • Design web layouts using HTML
  • Apply styling techniques using CSS
  • Implement game logic using JavaScript
  • Manipulate the Document Object Model (DOM)
  • Handle events and user interactions
  • Create and manage game state variables
  • Modify and update the game display dynamically
  • Test and debug the game implementation

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL css(("`CSS`")) -.-> css/BasicConceptsGroup(["`Basic Concepts`"]) css(("`CSS`")) -.-> css/BasicStylingGroup(["`Basic Styling`"]) css(("`CSS`")) -.-> css/CoreLayoutGroup(["`Core Layout`"]) css(("`CSS`")) -.-> css/IntermediateStylingGroup(["`Intermediate Styling`"]) css(("`CSS`")) -.-> css/DynamicStylingGroup(["`Dynamic Styling`"]) css(("`CSS`")) -.-> css/CSSPreprocessorsGroup(["`CSS Preprocessors`"]) css(("`CSS`")) -.-> css/CodingStandardsandBestPracticesGroup(["`Coding Standards and Best Practices`"]) html(("`HTML`")) -.-> html/BasicStructureGroup(["`Basic Structure`"]) html(("`HTML`")) -.-> html/TextContentandFormattingGroup(["`Text Content and Formatting`"]) html(("`HTML`")) -.-> html/LayoutandSectioningGroup(["`Layout and Sectioning`"]) html(("`HTML`")) -.-> html/FormsandInputGroup(["`Forms and Input`"]) javascript(("`JavaScript`")) -.-> javascript/BasicConceptsGroup(["`Basic Concepts`"]) javascript(("`JavaScript`")) -.-> javascript/AdvancedConceptsGroup(["`Advanced Concepts`"]) javascript(("`JavaScript`")) -.-> javascript/DOMManipulationGroup(["`DOM Manipulation`"]) javascript(("`JavaScript`")) -.-> javascript/ToolsandEnvironmentGroup(["`Tools and Environment`"]) javascript(("`JavaScript`")) -.-> javascript/SecurityGroup(["`Security`"]) css/BasicConceptsGroup -.-> css/selectors("`Selectors`") css/BasicStylingGroup -.-> css/colors("`Colors`") css/BasicStylingGroup -.-> css/fonts("`Fonts`") css/BasicStylingGroup -.-> css/text_styling("`Text Styling`") css/CoreLayoutGroup -.-> css/margin_and_padding("`Margin and Padding`") css/CoreLayoutGroup -.-> css/borders("`Borders`") css/CoreLayoutGroup -.-> css/width_and_height("`Width and Height`") css/CoreLayoutGroup -.-> css/positioning("`Positioning`") css/IntermediateStylingGroup -.-> css/backgrounds("`Backgrounds`") css/DynamicStylingGroup -.-> css/transitions("`Transitions`") css/CSSPreprocessorsGroup -.-> css/nesting("`Nesting`") css/CodingStandardsandBestPracticesGroup -.-> css/comments("`Comments`") html/BasicStructureGroup -.-> html/basic_elems("`Basic Elements`") html/BasicStructureGroup -.-> html/charset("`Character Encoding`") html/BasicStructureGroup -.-> html/head_elems("`Head Elements`") html/TextContentandFormattingGroup -.-> html/text_head("`Text and Headings`") html/LayoutandSectioningGroup -.-> html/doc_flow("`Document Flow Understanding`") html/FormsandInputGroup -.-> html/forms("`Form Elements`") css/IntermediateStylingGroup -.-> css/pseudo_classes("`Pseudo-classes`") javascript/BasicConceptsGroup -.-> javascript/variables("`Variables`") javascript/BasicConceptsGroup -.-> javascript/data_types("`Data Types`") javascript/BasicConceptsGroup -.-> javascript/arith_ops("`Arithmetic Operators`") javascript/BasicConceptsGroup -.-> javascript/comp_ops("`Comparison Operators`") javascript/BasicConceptsGroup -.-> javascript/cond_stmts("`Conditional Statements`") javascript/BasicConceptsGroup -.-> javascript/loops("`Loops`") javascript/BasicConceptsGroup -.-> javascript/functions("`Functions`") javascript/BasicConceptsGroup -.-> javascript/str_manip("`String Manipulation`") javascript/BasicConceptsGroup -.-> javascript/array_methods("`Array Methods`") javascript/BasicConceptsGroup -.-> javascript/obj_manip("`Object Manipulation`") javascript/AdvancedConceptsGroup -.-> javascript/oop("`Object-Oriented Programming`") javascript/AdvancedConceptsGroup -.-> javascript/async_prog("`Asynchronous Programming`") javascript/AdvancedConceptsGroup -.-> javascript/closures("`Closures`") javascript/DOMManipulationGroup -.-> javascript/dom_select("`DOM Selection`") javascript/DOMManipulationGroup -.-> javascript/dom_manip("`DOM Manipulation`") javascript/DOMManipulationGroup -.-> javascript/event_handle("`Event Handling`") javascript/DOMManipulationGroup -.-> javascript/dom_traverse("`DOM Traversal`") javascript/ToolsandEnvironmentGroup -.-> javascript/bom("`Browser Object Model`") javascript/SecurityGroup -.-> javascript/xss("`Cross-Site Scripting`") subgraph Lab Skills css/selectors -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/colors -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/fonts -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/text_styling -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/margin_and_padding -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/borders -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/width_and_height -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/positioning -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/backgrounds -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/transitions -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/nesting -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/comments -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} html/basic_elems -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} html/charset -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} html/head_elems -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} html/text_head -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} html/doc_flow -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} html/forms -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} css/pseudo_classes -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/variables -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/data_types -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/arith_ops -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/comp_ops -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/cond_stmts -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/loops -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/functions -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/str_manip -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/array_methods -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/obj_manip -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/oop -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/async_prog -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/closures -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/dom_select -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/dom_manip -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/event_handle -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/dom_traverse -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/bom -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} javascript/xss -.-> lab-298949{{"`Building a Web Avoiding Block Game`"}} end

Designing the Game Layout with HTML

Requirements:

  • Open the index.html file.
  • Familiarity with HTML tags and structure.

Functionality:

  • Layout the main game container.
  • Display the game's score.
  • Provide a start button to initiate the game.

Steps:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Avoid the white block</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <h2>score</h2>
    <h2 id="score">0</h2>
    <div id="main">
      <div id="con"></div>
      <!-- Game container -->
    </div>
    <div class="btn">
      <button class="start" onclick="start()">Start</button>
      <!-- Start button -->
    </div>
  </body>
  <script src="script.js"></script>
</html>

In above code, we have created a basic HTML structure for our game. We have a div with id="main" which will be our game container. Inside the game container, we have another div with id="con" which will be our player. We have also created a button with class="start" which will be used to start the game.

Add Styling to the Game

Requirements:

  • Open the styles.css file.
  • Basic knowledge of CSS properties and selectors.
  • Understanding of styling techniques for responsive designs.

Functionality:

  • Enhance the game's visual appeal.
  • Make the game interface responsive to different screen sizes.

Steps:

body {
  background-color: #f0f0f0;
  font-family: "Arial", sans-serif;
}
h2 {
  text-align: center;
  color: #333;
  margin-bottom: 8px;
}
#main {
  width: 408px;
  height: 408px;
  background: white;
  border: 8px solid #ccc;
  border-radius: 10px;
  /* Added border-radius for a softer look */
  margin: 20px auto;
  overflow: hidden;
  position: relative;
  /* Added relative positioning for child positioning */
}
#con {
  width: 100%;
  height: 400px;
  position: absolute;
  /* Changed to absolute */
  top: -408px;
}
.row {
  height: 100px;
  width: 100%;
}
.cell {
  height: 100px;
  width: 100px;
  float: left;
  border-bottom: rgb(200, 200, 200) 1px solid;
  /* Lighter border color */
}
.black {
  background: #444;
  /* Dark grey instead of black for a softer look */
}
.btn {
  width: 100%;
  text-align: center;
  margin-top: 20px;
}
.start {
  margin: 20px auto;
  width: 150px;
  height: 50px;
  border-radius: 25px;
  /* Increased border-radius for a pill shape */
  background: #4caf50;
  /* Green button */
  color: #fff;
  font-size: 16px;
  /* Increased font size */
  border: none;
  /* Remove default border */
  cursor: pointer;
  /* Cursor effect */
  transition: background 0.3s;
  /* Transition effect */
}
.start:hover {
  background: #45a049;
  /* Darker green on hover */
}

In above code, we have added some basic styling to our game. We have added a background color to the body and a font family to the text. We have also added a border radius to the game container to make it look softer. We have also added a position: relative to the game container and position: absolute to the player. This will allow us to position the player inside the game container. We have also added a transition effect to the start button.

Implement the Basic Game Logic

Requirements:

  • Open the script.js file.
  • Preliminary grasp of JavaScript basics.
  • Understand the concept of the Document Object Model (DOM).

Functionality:

  • Set up essential utility functions.
  • Initialize crucial game state variables.

Steps:

// Utility functions and initial variable setup
// Get an element by its id
function $(id) {
  return document.getElementById(id);
}

// Create a div element with a given class name
function creatediv(className) {
  var div = document.createElement("div");
  div.className = className;
  return div;
}
// Set an interval id as null initially
var clock = null;
// State of the game (0 means stopped and 1 means started)
var state = 0;
// Speed of the game blocks movement
var speed = 6;
// Flag to check if the game has started or not
var flag = false;

In above code, we have created two utility functions. The first function $(id) is used to get an element by its id. The second function creatediv(className) is used to create a div element with a given class name. We have also initialized some variables which will be used later in the game.

Initialize the Game

Requirements:

  • Ability to craft JavaScript functions.
  • Familiarity with JavaScript event listeners.

Functionality:

  • Prepare the game to be launch-ready.
  • Create the game's initial set of blocks.

Steps:

// Clicking the start game button to start the game
function start() {
  if (!flag) {
    init();
  } else {
    alert("The game has already started! No need to click again!");
  }
}

// Initialization (init) function
function init() {
  flag = true;
  for (var i = 0; i < 4; i++) {
    createrow();
  }

  // Adding event listeners with addEventListener
  $("main").addEventListener("click", function (ev) {
    judge(ev);
  });

  // Timer call move() every 30 milliseconds
  clock = setInterval(move, 30);
}

In above code, we have created a start() function which will be called when the start button is clicked. Inside the start() function, we have called the init() function which will initialize the game. Inside the init() function, we have set the flag variable to true which will be used to check if the game has started or not. We have also created four rows of blocks using the createrow() function. We have also added an event listener to the game container which will be used to detect the click event on the game container. We have also set a timer which will call the move() function every 30 milliseconds.

Implement Gameplay Functionality

Requirements:

  • Proficiency with JavaScript loops and conditions.
  • Know-how to manipulate the DOM using JavaScript.

Functionality:

  • Craft the core game dynamics.
  • Design game-over scenarios.
  • Implement mechanics for block creation and movement.

Steps:

  1. Check whether the player has clicked on a black or white block. Update game status based on the player's click.
// Determine whether to click on a black or white block
function judge(ev) {
  if (
    ev.target.className.indexOf("black") == -1 &&
    ev.target.className.indexOf("cell") !== -1
  ) {
    ev.target.parentNode.pass1 = 1; // Defines the pass attribute, which indicates that the white block of this row has been clicked
  }

  if (ev.target.className.indexOf("black") !== -1) {
    // Clicking a target with black in the class name is a black block
    ev.target.className = "cell";
    ev.target.parentNode.pass = 1; // Defines the pass attribute, indicating the black block in this row was clicked
    score();
  }
}
  1. Determine when the game is over based on player interactions. Trigger game-ending actions when the game is over.
// Check if the game is over
function over() {
  var rows = con.childNodes;
  if (rows.length == 5 && rows[rows.length - 1].pass !== 1) {
    fail();
  }
  for (let i = 0; i < rows.length; i++) {
    if (rows[i].pass1 == 1) {
      fail();
    }
  }
}

// Game Over
function fail() {
  clearInterval(clock);
  flag = false;
  confirm("The final score is " + parseInt($("score").innerHTML));
  var con = $("con");
  con.innerHTML = "";
  $("score").innerHTML = 0;
  con.style.top = "-408px";
}
  1. Generate rows of blocks for gameplay. Randomly position the "black" block amongst others.
// Create a <div class="row"> with four children <div class="cell">
function createrow() {
  var con = $("con");
  var row = creatediv("row"); // Create div: className=row
  var arr = creatcell(); // Define the class name of the div cell, one of which is cell black

  con.appendChild(row); // Add child node with row as con

  for (var i = 0; i < 4; i++) {
    row.appendChild(creatediv(arr[i])); // Add child nodes of row cell
  }

  if (con.firstChild == null) {
    con.appendChild(row);
  } else {
    con.insertBefore(row, con.firstChild);
  }
}

// Create an array of class names; one of them is "cell black", others are "cell"
function creatcell() {
  var temp = ["cell", "cell", "cell", "cell"];
  var i = Math.floor(Math.random() * 4); // Randomly generate the position of the black block Math.random() function parameters 0~1 random number
  temp[i] = "cell black";
  return temp;
}
  1. Make blocks move downwards continuously. Delete old rows as they move out of view.
// Move the black blocks down
function move() {
  var con = $("con");
  var top = parseInt(window.getComputedStyle(con, null)["top"]);

  if (speed + top > 0) {
    top = 0;
  } else {
    top += speed;
  }
  con.style.top = top + "px"; // Keep moving the top value so it moves
  over();
  if (top == 0) {
    createrow();
    con.style.top = "-102px";
    delrow();
  }
}

// Delete a row
function delrow() {
  var con = $("con");
  if (con.childNodes.length == 6) {
    con.removeChild(con.lastChild);
  }
}

Finalize Game Scoring and Speed Management

Requirements:

  • Understand JavaScript variables and arithmetic operations.
  • Ability to write complex game logic in JavaScript.

Functionality:

  • Establish a reward system.
  • Create a system to progressively increase the game's difficulty.

Steps:

// Acceleration function, increases the speed
function speedup() {
  speed += 2;
  if (speed == 20) {
    alert("That's awesome!");
  }
}
// Scoring
function score() {
  var newscore = parseInt($("score").innerHTML) + 1; // point plus one
  $("score").innerHTML = newscore; // Modify Score
  if (newscore % 10 == 0) {
    // Use the acceleration function when the fraction is a multiple of 10, it gets faster and faster
    speedup();
  }
}

In above code, we have created a speedup() function which will be used to increase the speed of the game. We have also created a score() function which will be used to increase the score of the game. We have also added a condition in the score() function which will call the speedup() function when the score is a multiple of 10.

Test Your Game

  • Open index.html in a web browser.

    open web
  • Play the game, ensuring all functionalities work as expected.

  • The effect of the page is as follows:

    effect

Summary

Great job! You've just built a simple but fun avoiding block game from scratch using HTML, CSS, and JavaScript. This project introduced you to handling user interaction, game logic, and dynamic CSS styling based on game state changes. You can extend this base game with more features like levels, time limits, or various difficulty modes. Enjoy experimenting with your new game!

Other JavaScript Tutorials you may like