Gaming Health Meter with CSS3

Table of Contents

 

Introduction

Many games are designed with common elements such as game indicators (for health, magic, ammo, money, etc ...), control and status panels that sit around the edges of the game. They are part of the game, but not necessarily part of the main graphics scene.

In HTML5, the main graphics area is often created with a canvas tag. The developer then writes JavaScript* to draw in the canvas area and create the game. It make sense to pull gaming elements that are not part of the main graphics scene out of the canvas element for a couple of reasons.

First, objects that can be animated in the DOM using CSS animations and transitions often enjoy better browser optimization and even hardware acceleration. That is, animations that can be performed in CSS will perform better than those in JavaScript*.

Second, objects that are drawn in a canvas tag with JavaScript* can not be manipulated by the DOM or by CSS. So by moving elements of the game into the main HTML document and simply positioning them over your canvas element, you can achieve the same look, but use the power of CSS3, as well as JavaScript* to manipulate them.

During the rest of this article, we'll build a meter and for the purposes of this article we'll make it a health meter.

Basic Meter

First the basic HTML markup:

<html>
  <body>
    <style>
      #meter-container {
        width: 300px; 
      }
      .meter { 
        height: 10px;  
        position: relative;      
        background: #333;
        
        border: 1px solid black;
        -moz-border-radius: 30px;
        -webkit-border-radius: 30px;
        border-radius: 30px;
        
        padding: 10px;
        
        -webkit-box-shadow: inset 0 -1px 1px rgba(255,255,255,0.3);
        -moz-box-shadow   : inset 0 -1px 1px rgba(255,255,255,0.3);
        box-shadow        : inset 0 -1px 1px rgba(255,255,255,0.3);
      }
      
      .strong-health {
        background-color: #7eff00; 
        width: 85%;
      }
      
      .weak-health {
        background-color: #ff0; 
        width: 35%;        
      }
      
      .danger-health {
        background-color: #f00;
        width: 10%;        
      }
      
      .meter-value {
        /* Position the value */
        position: absolute;
        top: 0; left: 0; bottom: 0; right: 0;
   
        -webkit-border-top-right-radius: 5px;
        -webkit-border-bottom-right-radius: 5px;
        -moz-border-radius-topright: 5px;
        -moz-border-radius-bottomright: 5px;
        border-top-right-radius: 5px;
        border-bottom-right-radius: 5px;
        
        -webkit-border-top-left-radius: 20px;
        -webkit-border-bottom-left-radius: 20px;
        -moz-border-radius-topleft: 20px;
        -moz-border-radius-bottomleft: 20px;
        border-top-left-radius: 20px;
        border-bottom-left-radius: 20px;      
      }
    </style>
    <div id="meter-container">     
      
      <div class="meter">
        <div class="meter-value strong-health">
        </div>
        
      </div>
    </div>
    
  </body>
</html>

We can use this to create three styles of health meter.

 

Danger Health Meter

 

Weak Health Meter

 

Strong Health Meter

These meters aren't too bad and the only bit of CSS3 that we've used is border-radius which lets us round the corners of the life meter.

Adding CSS Gradients to the Meter

#gradient-example .strong-health {
        background-color: #7eff00;         
        background-image: -moz-linear-gradient(top, #78F165, #0CF30C);
        background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #78F165),color-stop(1, #0CF30C));
        background-image: -webkit-linear-gradient(#78F165, #0CF30C); 
        width: 85%;
}
      
      #gradient-example .weak-health {
        background-color: #ff0; 
        width: 35%;  
        background-color: #f1a165;
        background-image: -moz-linear-gradient(top, #F1F165, #F3F30C);
        background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #F1F165),color-stop(1, #F3F30C));
        background-image: -webkit-linear-gradient(#F1F165, #F3F30C); 
}
      
      #gradient-example .danger-health {
        background-color: #f00;
        width: 15%;        
        background-color: #f0a3a3;
        background-image: -moz-linear-gradient(top, #f0a3a3, #f42323);
        background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #f0a3a3),color-stop(1, #f42323));
        background-image: -webkit-linear-gradient(#f0a3a3, #f42323);
}
 

Danger Health Meter

 

Weak Health Meter

 

Strong Health Meter

CSS gradients work much like gradients in other graphics tools, such as Adobe Photoshop* or the GIMP, work. You define a transition type, such as linear or radial, and then you define a starting point color and an ending point color. The gradient will smoothly transition between the two. You can also define any number of stopping points that allow you to transition to an intermediate color before continuing to the next stopping color or the finishing color.

These CSS gradients are subtle, but they let the color of the life meter stand out against the background. Also at this point you should check that you are viewing this article in a CSS3 enabled browser; Microsoft Internet Explorer* 9+, Firefox*, Opera*, Safari* or Chrome*. Otherwise you won't be able to see the gradients.

Adding CSS Animation to the Meter

The markup is the same.

     
      @-webkit-keyframes glow {
	0% {
          -webkit-box-shadow: 0 0 16px rgba(240, 163, 163, 0.5);
          border-color: rgba(0,0,255,0.5); 		
	}
	100% {
          -webkit-box-shadow: 0 0 16px rgba(240, 0, 0, 1.0), 0 0 36px rgba(240, 0, 0, 1.0);
          border-color: rgba(0,0,255,1.0); 
	}
      }

     @-moz-keyframes glow {
	0% {
          -moz-box-shadow: 0 0 16px rgba(240, 163, 163, 0.5);
          border-color: rgba(0,0,255,0.5); 		
	}
	100% {
          -moz-box-shadow: 0 0 16px rgba(240, 0, 0, 1.0), 0 0 36px rgba(240, 0, 0, 1.0);
          border-color: rgba(0,0,255,1.0); 
	}
      }

     @-ms-keyframes glow {
	0% {
          -ms-box-shadow: 0 0 16px rgba(240, 163, 163, 0.5);
          border-color: rgba(0,0,255,0.5); 		
	}
	100% {
          -ms-box-shadow: 0 0 16px rgba(240, 0, 0, 1.0), 0 0 36px rgba(240, 0, 0, 1.0);
          border-color: rgba(0,0,255,1.0); 
	}
      }
 
      #animation-example .danger-health {
        background-color: #f00;
        width: 15%;     
        background-color: #f0a3a3;
        background-image: -moz-linear-gradient(top, #f0a3a3, #f42323);
        background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #f0a3a3),color-stop(1, #f42323));
        background-image: -webkit-linear-gradient(#f0a3a3, #f42323);
        
        -webkit-animation-name: glow;
	-webkit-animation-duration: 0.5s;
	-webkit-animation-iteration-count: infinite;
	-webkit-animation-direction: alternate;
	-webkit-animation-timing-function: ease-in-out;	
	
	-moz-animation-name: glow;
	-moz-animation-duration: 1s;
	-moz-animation-iteration-count: infinite;
	-moz-animation-direction: alternate;
	-moz-animation-timing-function: ease-in-out;
	
	-ms-animation-name: glow;
	-ms-animation-duration: 1s;
	-ms-animation-iteration-count: infinite;
	-ms-animation-direction: alternate;
	-ms-animation-timing-function: ease-in-out;
      }

The danger-health meter:

Now the danger-health meter glows to draw the player attention to their critical health

 

CSS animations allow the browser to transition between one set of CSS styles to another set of CSS styles. You can also define intermediate styles for your animation. In this case, I only define two styles. The first is at 0% or the beginning of the animation. The second is at 100% or the end of the animation. In order to create the glowing effect, the browser will smoothly transition the box-shadow property from small to a larger size.

Adding Web Fonts to the Meter

Finally, I'm going to add the percentage to the meter by getting a web font from the Google* Web font page.

Link to the web font. Google has created these fonts to be publicly available and royalty free.

<link href='http://fonts.googleapis.com/css?family=Chewy' rel='stylesheet' type='text/css'>

Create some CSS rules for this text.

.textbox {
        font-size: 40px;
        color: #fff;        
        font-family: 'Chewy', cursive, helvetica, arial, sans-serif;
        text-shadow: 2px 3px 1px #000;
        letter-spacing: 0px;
        -webkit-text-fill-color: #fff; 
        -webkit-text-stroke-width: 1px;
        -webkit-text-stroke-color: black;

        text-align: center;
        text-transform:uppercase;
      }

Here is the HTML markup for the meters

<div id="animation-example">
    <link href='http://fonts.googleapis.com/css?family=Chewy' rel='stylesheet' type='text/css'>

  <div class="container">
    <div class="meter">
      <div class="textbox">15%</div>
      <div class="meter-value danger-health">
      </div> 
    </div>
    <p>Danger Health Meter</p>

    <div class="meter">
       <div class="textbox">35%</div>
      <div class="meter-value weak-health">
      </div>
    </div>
    <p>Weak Health Meter</p>

    <div class="meter">
      <div class="textbox">85%</div>   
      <div class="meter-value strong-health">
      </div>
    </div>
    <p>Strong Health Meter</p>
  </div>
</div>
</div>
 
15%
 

Danger Health Meter

35%
 

Weak Health Meter

85%
 

Strong Health Meter

For more complete information about compiler optimizations, see our Optimization Notice.