Tower Blocks Game Using HTML CSS And JavaScript

Tower Blocks Game Using HTML CSS And JavaScript

Introduction

Hello coders, welcome to another new blog. Today in this blog we’ll learn to create a Tower Block game. We’ve used HTML CSS and JavaScript to create our Tower Block game. In this game we’ve have set blocks on one another and with each set block our score increases.

We’ve used HTML CSS and JavaScript to create this game. In our Tower Block game, HTML sets up the basic structure of our game and set elements for our game. CSS designs our Tower block game. At last, the main part comes JavaScript. JavaScript and its libraries adds interactive functionality to our game.

If you also want to create this type of game then you should have knowledge of HTML CSS and JavaScript. If you’ve have good amount of knowledge and skills in these technologies then you’re good to go. These type of project always enhance our coding skills and gives a satisfaction. Let’s understand our code.

HTML (index.html)

Get Discount on Top Educational Courses

Brand NameDiscount InformationCoupon Codes Link
Educative.io20% discount on Educative courses and plans
W3Schools20% discount on W3Schools courses
KodeKloud10% discount on KodeKloud courses and plans
GeeksforGeeks30% discount on GeeksforGeeks courses
Target Test Prep20% discount on Target Test Prep
Coding Ninjas₹5000 discount on Coding Ninjas courses
Skillshare40% discount on Skillshare
DataCamp50% discount on DataCamp
365 Data Science57% discount on 365 Data Science Plans
Get SmarterFlat 20% discount on Get Smarter courses
SmartKeedaFlat 40% discount on SmartKeeda courses
StackSocial20% discount on StackSocial courses

This is our HTML code which sets up the basic structure for our Tower Block game. Using this HTML code build basic elements of our game. Let’s breakdown our code.

  • <!DOCTYPE html> : It defines the type of our document and ensures that our document is a HTML file document.
  • <title> : This sets title for our webpage as Tower Blocks.
  • <script> : It adds external JavaScript libraries cdn which we can use in our JavaScript file.
  • <link> : This tag links external CSS file in our code.
  • <script src=”script.js”> : This adds external JavaScript file in our code and ensures to load asynchronously.
  • <div id=”container”> : This contains all the game content in main container div.
  • <div id=”game”> : This represent the main game area content which we’ll design using JS.
  • <div id=”score”> : This displays the in game score of the player.
  • <div id=”instruction”> : This displays instruction to play the game .
  • <div class =” game-over”> : A h2 and 2 paragraph tags are in this div which will represent the game over condition.
  • <div class=”game-ready”> : This will represent the start of the game condition where user can start the game.
				
					

  
    
    
    
    
    
    
    <title>Tower Blocks</title>
    

    
  
  
    
    <div id="container">
      <div id="game"></div>
      <div id="score">0</div>
      <div id="instructions">
        Click (or press the spacebar) to place the block
      </div>
      <div class="game-over">
        <h2>Game Over</h2>
        <p>You did great, you're the best.</p>
        <p>Click or spacebar to start again</p>
      </div>
      <div class="game-ready">
        <div id="start-button">Start</div>
        <div></div>
      </div>
    </div>
    <footer>Project By -: TANAY PADAR</footer>
  


				
			

CSS (Style.css)

This is our CSS code which designs our Tower blocks game. CSS is used to design web pages. CSS makes our webpage visually appealing. Let’s breakdown our CSS code.

  • Our code starts by importing the google font “Comfortaa”.
  • The html and body sets full height and width and removes margin. It sets overflow hidden and position relative.
  • The #conatainer sets 100% height and width.
  • The #score sets 100% width, displays the score in the center, and applies animation using transition and transform properties. Position set as absolute.
  • The #game takes full area by applying all sides as 0 and sets position as absolute.
  • The .game-over sets position absolute with top left of 0 and width of 100%. It sets height 85% and center the elements using flexbox.
  • A transition is applied to the .game-over class.
  • .game-ready takes full height and width and center the elements using flexbox. It also sets position absolute with top and left of 0.
  • The #start-button styled with animation and fade movement. It sets transition properties and displays the big font size with transparent background.
  • #instruction sets position absolute, 100% width, top 16vh and left 0. It centers the text and adds some animation.
  • All the .playing .resetting .ready .ended classes handles the animation for various states of the game.
				
					@import url("https://fonts.googleapis.com/css?family=Comfortaa");
html,
body {
  margin: 0;
  overflow: hidden;
  height: 100%;
  width: 100%;
  position: relative;
  font-family: "Comfortaa", cursive;
}
#container {
  width: 100%;
  height: 100%;
}
#container #score {
  position: absolute;
  top: 20px;
  width: 100%;
  text-align: center;
  font-size: 10vh;
  transition: transform 0.5s ease;
  color: #334;
  transform: translatey(-200px) scale(1);
}
#container #game {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
#container .game-over {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 85%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
#container .game-over * {
  transition: opacity 0.5s ease, transform 0.5s ease;
  opacity: 0;
  transform: translatey(-50px);
  color: #334;
}
#container .game-over h2 {
  margin: 0;
  padding: 0;
  font-size: 40px;
}
#container .game-ready {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
}
#container .game-ready #start-button {
  transition: opacity 0.5s ease, transform 0.5s ease;
  opacity: 0;
  transform: translatey(-50px);
  border: 3px solid #334;
  padding: 10px 20px;
  background-color: transparent;
  color: #334;
  font-size: 30px;
}
#container #instructions {
  position: absolute;
  width: 100%;
  top: 16vh;
  left: 0;
  text-align: center;
  transition: opacity 0.5s ease, transform 0.5s ease;
  opacity: 0;
}
#container #instructions.hide {
  opacity: 0 !important;
}
#container.playing #score,
#container.resetting #score {
  transform: translatey(0px) scale(1);
}
#container.playing #instructions {
  opacity: 1;
}
#container.ready .game-ready #start-button {
  opacity: 1;
  transform: translatey(0);
}
#container.ended #score {
  transform: translatey(6vh) scale(1.5);
}
#container.ended .game-over * {
  opacity: 1;
  transform: translatey(0);
}
#container.ended .game-over p {
  transition-delay: 0.3s;
}

				
			

Javascript (Script.js)

This is our JavaScript code which is the most important code for our Towe Block game. This code adds interactive functionality in our game. In our code we’ve used Three.js , TweenMax.js and JavaScript to make our game animated and visually appealing with proper functionality.

Three.js is generally used to make 3D websites. This is a JavaScript library which is widely used in market to make 3D and animated stuff. We’ve used TweenMax.js in our code as well. TweenMax.js animates any property of any object which JavaScript can touch. This library of JavaScript is mainly used to add animations.

In our JavaScript code we’ve used all these libraries to make our Tower block game user interactive. This game is well designed and works good too. Let’s understand our code in short and easy way.

  • Stage class: It handles the 3D visuals set up using Three.js library.
  • This class initialize the game container, renderer, scene and lights.
  • This class controls the camera movement as well using Tweenlight.
  • Block class : In the state management section it handles the active, stopped and missed state of blocks.
  • This class controls the size, position and color of the block.
  • Movement and direction controls are setup by this class.
  • Game class: This class handles all the game logic.
  • This class controls the different stages of the game like playing, ready , ending etc.
  • It adds blocks and handles their placing in game and updates the score as well.
  • It also handles reset and restart game state.
  • Game mechanics : This section controls the adding of new block, camera position and all the block placements.
  • At last rendering section uses the tick method to update the game and render each frame continuously.
				
					console.clear();
var Stage = /** @class */ (function () {
  function Stage() {
    // container
    var _this = this;
    this.render = function () {
      this.renderer.render(this.scene, this.camera);
    };
    this.add = function (elem) {
      this.scene.add(elem);
    };
    this.remove = function (elem) {
      this.scene.remove(elem);
    };
    this.container = document.getElementById("game");
    // renderer
    this.renderer = new THREE.WebGLRenderer({
      antialias: true,
      alpha: false,
    });
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.setClearColor("#D0CBC7", 1);
    this.container.appendChild(this.renderer.domElement);
    // scene
    this.scene = new THREE.Scene();
    // camera
    var aspect = window.innerWidth / window.innerHeight;
    var d = 20;
    this.camera = new THREE.OrthographicCamera(
      -d * aspect,
      d * aspect,
      d,
      -d,
      -100,
      1000
    );
    this.camera.position.x = 2;
    this.camera.position.y = 2;
    this.camera.position.z = 2;
    this.camera.lookAt(new THREE.Vector3(0, 0, 0));
    //light
    this.light = new THREE.DirectionalLight(0xffffff, 0.5);
    this.light.position.set(0, 499, 0);
    this.scene.add(this.light);
    this.softLight = new THREE.AmbientLight(0xffffff, 0.4);
    this.scene.add(this.softLight);
    window.addEventListener("resize", function () {
      return _this.onResize();
    });
    this.onResize();
  }
  Stage.prototype.setCamera = function (y, speed) {
    if (speed === void 0) {
      speed = 0.3;
    }
    TweenLite.to(this.camera.position, speed, {
      y: y + 4,
      ease: Power1.easeInOut,
    });
    TweenLite.to(this.camera.lookAt, speed, { y: y, ease: Power1.easeInOut });
  };
  Stage.prototype.onResize = function () {
    var viewSize = 30;
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.camera.left = window.innerWidth / -viewSize;
    this.camera.right = window.innerWidth / viewSize;
    this.camera.top = window.innerHeight / viewSize;
    this.camera.bottom = window.innerHeight / -viewSize;
    this.camera.updateProjectionMatrix();
  };
  return Stage;
})();
var Block = /** @class */ (function () {
  function Block(block) {
    // set size and position
    this.STATES = { ACTIVE: "active", STOPPED: "stopped", MISSED: "missed" };
    this.MOVE_AMOUNT = 12;
    this.dimension = { width: 0, height: 0, depth: 0 };
    this.position = { x: 0, y: 0, z: 0 };
    this.targetBlock = block;
    this.index = (this.targetBlock ? this.targetBlock.index : 0) + 1;
    this.workingPlane = this.index % 2 ? "x" : "z";
    this.workingDimension = this.index % 2 ? "width" : "depth";
    // set the dimensions from the target block, or defaults.
    this.dimension.width = this.targetBlock
      ? this.targetBlock.dimension.width
      : 10;
    this.dimension.height = this.targetBlock
      ? this.targetBlock.dimension.height
      : 2;
    this.dimension.depth = this.targetBlock
      ? this.targetBlock.dimension.depth
      : 10;
    this.position.x = this.targetBlock ? this.targetBlock.position.x : 0;
    this.position.y = this.dimension.height * this.index;
    this.position.z = this.targetBlock ? this.targetBlock.position.z : 0;
    this.colorOffset = this.targetBlock
      ? this.targetBlock.colorOffset
      : Math.round(Math.random() * 100);
    // set color
    if (!this.targetBlock) {
      this.color = 0x333344;
    } else {
      var offset = this.index + this.colorOffset;
      var r = Math.sin(0.3 * offset) * 55 + 200;
      var g = Math.sin(0.3 * offset + 2) * 55 + 200;
      var b = Math.sin(0.3 * offset + 4) * 55 + 200;
      this.color = new THREE.Color(r / 255, g / 255, b / 255);
    }
    // state
    this.state = this.index &gt; 1 ? this.STATES.ACTIVE : this.STATES.STOPPED;
    // set direction
    this.speed = -0.1 - this.index * 0.005;
    if (this.speed  0.5 ? -this.MOVE_AMOUNT : this.MOVE_AMOUNT;
    }
  }
  Block.prototype.reverseDirection = function () {
    this.direction = this.direction &gt; 0 ? this.speed : Math.abs(this.speed);
  };
  Block.prototype.place = function () {
    this.state = this.STATES.STOPPED;
    var overlap =
      this.targetBlock.dimension[this.workingDimension] -
      Math.abs(
        this.position[this.workingPlane] -
          this.targetBlock.position[this.workingPlane]
      );
    var blocksToReturn = {
      plane: this.workingPlane,
      direction: this.direction,
    };
    if (this.dimension[this.workingDimension] - overlap  0) {
      var choppedDimensions = {
        width: this.dimension.width,
        height: this.dimension.height,
        depth: this.dimension.depth,
      };
      choppedDimensions[this.workingDimension] -= overlap;
      this.dimension[this.workingDimension] = overlap;
      var placedGeometry = new THREE.BoxGeometry(
        this.dimension.width,
        this.dimension.height,
        this.dimension.depth
      );
      placedGeometry.applyMatrix(
        new THREE.Matrix4().makeTranslation(
          this.dimension.width / 2,
          this.dimension.height / 2,
          this.dimension.depth / 2
        )
      );
      var placedMesh = new THREE.Mesh(placedGeometry, this.material);
      var choppedGeometry = new THREE.BoxGeometry(
        choppedDimensions.width,
        choppedDimensions.height,
        choppedDimensions.depth
      );
      choppedGeometry.applyMatrix(
        new THREE.Matrix4().makeTranslation(
          choppedDimensions.width / 2,
          choppedDimensions.height / 2,
          choppedDimensions.depth / 2
        )
      );
      var choppedMesh = new THREE.Mesh(choppedGeometry, this.material);
      var choppedPosition = {
        x: this.position.x,
        y: this.position.y,
        z: this.position.z,
      };
      if (
        this.position[this.workingPlane]  this.MOVE_AMOUNT || value &lt; -this.MOVE_AMOUNT)
        this.reverseDirection();
      this.position[this.workingPlane] += this.direction;
      this.mesh.position[this.workingPlane] = this.position[this.workingPlane];
    }
  };
  return Block;
})();
var Game = /** @class */ (function () {
  function Game() {
    var _this = this;
    this.STATES = {
      LOADING: &quot;loading&quot;,
      PLAYING: &quot;playing&quot;,
      READY: &quot;ready&quot;,
      ENDED: &quot;ended&quot;,
      RESETTING: &quot;resetting&quot;,
    };
    this.blocks = [];
    this.state = this.STATES.LOADING;
    this.stage = new Stage();
    this.mainContainer = document.getElementById(&quot;container&quot;);
    this.scoreContainer = document.getElementById(&quot;score&quot;);
    this.startButton = document.getElementById(&quot;start-button&quot;);
    this.instructions = document.getElementById(&quot;instructions&quot;);
    this.scoreContainer.innerHTML = &quot;0&quot;;
    this.newBlocks = new THREE.Group();
    this.placedBlocks = new THREE.Group();
    this.choppedBlocks = new THREE.Group();
    this.stage.add(this.newBlocks);
    this.stage.add(this.placedBlocks);
    this.stage.add(this.choppedBlocks);
    this.addBlock();
    this.tick();
    this.updateState(this.STATES.READY);
    document.addEventListener(&quot;keydown&quot;, function (e) {
      if (e.keyCode == 32) _this.onAction();
    });
    document.addEventListener(&quot;click&quot;, function (e) {
      _this.onAction();
    });
    document.addEventListener(&quot;touchstart&quot;, function (e) {
      e.preventDefault();
      // this.onAction();
      // ☝️ this triggers after click on android so you
      // insta-lose, will figure it out later.
    });
  }
  Game.prototype.updateState = function (newState) {
    for (var key in this.STATES)
      this.mainContainer.classList.remove(this.STATES[key]);
    this.mainContainer.classList.add(newState);
    this.state = newState;
  };
  Game.prototype.onAction = function () {
    switch (this.state) {
      case this.STATES.READY:
        this.startGame();
        break;
      case this.STATES.PLAYING:
        this.placeBlock();
        break;
      case this.STATES.ENDED:
        this.restartGame();
        break;
    }
  };
  Game.prototype.startGame = function () {
    if (this.state != this.STATES.PLAYING) {
      this.scoreContainer.innerHTML = &quot;0&quot;;
      this.updateState(this.STATES.PLAYING);
      this.addBlock();
    }
  };
  Game.prototype.restartGame = function () {
    var _this = this;
    this.updateState(this.STATES.RESETTING);
    var oldBlocks = this.placedBlocks.children;
    var removeSpeed = 0.2;
    var delayAmount = 0.02;
    var _loop_1 = function (i) {
      TweenLite.to(oldBlocks[i].scale, removeSpeed, {
        x: 0,
        y: 0,
        z: 0,
        delay: (oldBlocks.length - i) * delayAmount,
        ease: Power1.easeIn,
        onComplete: function () {
          return _this.placedBlocks.remove(oldBlocks[i]);
        },
      });
      TweenLite.to(oldBlocks[i].rotation, removeSpeed, {
        y: 0.5,
        delay: (oldBlocks.length - i) * delayAmount,
        ease: Power1.easeIn,
      });
    };
    for (var i = 0; i 
        newBlocks.placed.position[newBlocks.plane]
      ) {
        positionParams[newBlocks.plane] =
          "+=" + 40 * Math.abs(newBlocks.direction);
      } else {
        positionParams[newBlocks.plane] =
          "-=" + 40 * Math.abs(newBlocks.direction);
      }
      TweenLite.to(newBlocks.chopped.position, 1, positionParams);
      TweenLite.to(newBlocks.chopped.rotation, 1, rotationParams);
    }
    this.addBlock();
  };
  Game.prototype.addBlock = function () {
    var lastBlock = this.blocks[this.blocks.length - 1];
    if (lastBlock &amp;&amp; lastBlock.state == lastBlock.STATES.MISSED) {
      return this.endGame();
    }
    this.scoreContainer.innerHTML = String(this.blocks.length - 1);
    var newKidOnTheBlock = new Block(lastBlock);
    this.newBlocks.add(newKidOnTheBlock.mesh);
    this.blocks.push(newKidOnTheBlock);
    this.stage.setCamera(this.blocks.length * 2);
    if (this.blocks.length &gt;= 5) this.instructions.classList.add("hide");
  };
  Game.prototype.endGame = function () {
    this.updateState(this.STATES.ENDED);
  };
  Game.prototype.tick = function () {
    var _this = this;
    this.blocks[this.blocks.length - 1].tick();
    this.stage.render();
    requestAnimationFrame(function () {
      _this.tick();
    });
  };
  return Game;
})();
var game = new Game();

				
			
/* Styles for the container */ .download-container { font-family: Arial, sans-serif; text-align: center; /* Center the content horizontally */ } .timer-container { font-size: 24px; } .red-circle { display: inline-block; width: 40px; height: 40px; border: 2px solid red; border-radius: 50%; text-align: center; line-height: 36px; color: red; font-weight: bold; } .start-button { padding: 10px 20px; font-size: 18px; background-color: #4CAF50; color: white; border: none; cursor: pointer; margin-bottom: 20px; } .start-button:hover { background-color: #45a049; } .downloading-message { font-size: 18px; margin-top: 20px; display: none; }
Your download is starting now...
const startButton = document.querySelector('.start-button'); const timerContainer = document.querySelector('.timer-container'); const downloadingMessage = document.querySelector('.downloading-message'); let timer, countdown, isPaused = false; startButton.addEventListener('click', function () { // Open the new webpage with "dofollow" when the button is clicked window.open('https://codewithcurious.com/getsmarter-promo-code/', '_blank', 'noopener,noreferrer'); // Replace with desired URL countdown = 25; // Set countdown to 100 seconds startButton.style.display = 'none'; // Hide the button when clicked timerContainer.innerHTML = `Your download will begin in ${countdown} seconds.`; startTimer(); // Start the countdown // Listen for tab visibility change document.addEventListener('visibilitychange', handleVisibilityChange); }); function startTimer() { timer = setInterval(function () { if (!isPaused && countdown > 0) { countdown--; timerContainer.innerHTML = `Your download will begin in ${countdown} seconds.`; if (countdown === 0) { clearInterval(timer); timerContainer.innerHTML = ''; // Clear the timer message downloadingMessage.style.display = 'block'; // Show the downloading message // Open the download link with "nofollow" after the timer ends window.open('https://downgit.github.io/#/home?url=https://github.com/he-is-talha/html-css-javascript-games/tree/main/12-Type-Number-Guessing-Game', '_blank', 'nofollow'); // Show the button again after redirection setTimeout(function() { startButton.style.display = 'inline-block'; // Show the button again downloadingMessage.style.display = 'none'; // Hide the downloading message }, 2000); // Delay of 2 seconds before showing the button again } } }, 1000); // Decrease by 1 every second } function handleVisibilityChange() { if (document.hidden) { clearInterval(timer); // Pause the timer if the tab is hidden isPaused = true; } else { isPaused = false; // Resume the timer when the tab becomes visible startTimer(); // Start the timer again } }

Output:

Disclaimer: The code provided in this post is sourced from GitHub and is distributed under the MIT License. All credits for the original code go to the respective owner. We have shared this code for educational purposes only. Please refer to the original repository for detailed information and any additional usage rights or restrictions.

Windows 12 Notepad Using Python Introduction: In this article, we will create a Windows 12 Notepad using Python. If you are a …

Animated Search Bar using Html CSS And JavaScript Introduction Hello friends, all of you developers are welcome to today’s beautiful blog post. …

Best Quiz Game Using HTML CSS And JavaScript Introduction Hello coders, welcome to another new blog. Today in this article we’ll learn …

Tower Blocks Game Using HTML CSS And JavaScript Introduction Hello coders, welcome to another new blog. Today in this blog we’ll learn …

Get Huge Discounts
More Python Projects