css3-animations

Dino Pairs Game | Using CSS3 Animation

Today were talking about how I created my Dino Pairs Game using CSS3 animations. This tutorial only really works in Chrome because I’m using 3d transforms. The game is playable in Firefox but better in Chrome.

So yeah I’ve had a bit of time off and had a little dabble with games. I’ve been having a look at the canvas tag, looking at out of the box game development like Construct2 (which by the way is awesome for rapid development of HTML5 games). I’ve also had a look at impactjs but haven’t managed to get to grips with that yet. But my heart lies with CSS, I just get it. I find it easy can experiment with confidence and enjoy coding it. So over the next few weeks I’m going to be really pushing the boat out with CSS3 and trying new stuff little bits of tips and tricks to full blown posts like this one.
So where was I, oh yeah Dino pairs. So the idea behind this game is that my eldest son loves to play this game the traditional way so whilst playing one evening I thought I have a go at creating one on line to up my profile and get loads of people to link to my game.(Something like that anyway).

View DemoDownload

Hit the Deck

So first things first we need the image assets for the deck. As you can see, I aggregated all the images together into one image so later I could position the image as a background with CSS.

Dino Pairs Deck Image

So now that is done we can get on with the rest of the game.

HTML5 Page

The HTML is pretty straight forward but I have used HTML5 layout elements within the page.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<title>Dino Pairs Game - Using CSS3 Animation</title>
<link rel="stylesheet" href="css/dinogamev2.css" />
</head>
<body>
 <section id="gameStats">
  <p id="timer">Time: <span class="gameScore"></span></p>
  <p id="reset"><a class="gameReset" href="">Reset</a></p>
 </section>	
<section id="game">
 <section id="gameIntro">
  <p><a id="gamePlay" class="button" href="">Play</a></p>
 </section>
 <section id="gameComplete">
  <p id="top">Your time taken was <span class="gameScore"></span>.</p>
  <p><a class="gameReset button" href="">Play again</a></p>
 </section>					
  <div id="cards">
   <div class="card">
    <div class="face front"></div>
    <div class="face back"></div>
   </div> <!-- .card -->
  </div> <!-- #cards -->
</section> <!-- #game -->
<script src="http://code.jquery.com/jquery-1.7.min.js"></script>
<script src="js/dinopairsv2.js"></script>
</body>
</html>

As you can see we’ve got game stats section that holds all the information about the game. Then below that we have the game section that holds all the game elements like the gameIntro screen and and the gamecomplete screen and also a div called cards that is eventually going to hold the deck. Then within that we create one card with a div to hold the front and back of the card. We will clone this to create the rest of the cards. I’ve also got jquery in there because I’m lazy and can’t be bothered to write pure javascript and a link to my js file.

The Javascript

Ok so there’s a lot going on in the javascript so I’m only going to highlight a couple of things. I’ve commented all the code in the download to make it easier to understand but just can always ask me any questions in the comments below.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
//onclick function add flip class and then check to see if cards are the same
function selectCard() {
 // we do nothing if there are already two cards flipped.
 if ($(".card-flipped").size() > 1) {
  return;
 }
 $(this).addClass("card-flipped");
// check the pattern of both flipped card 0.7s later.
 if ($(".card-flipped").size() == 2) {
  setTimeout(checkPattern,700);
 }
}

So as I said we are concentrating on the CSS3 animations here. So the selectCard function runs when the card div is clicked. So first if there is more than 1 element with the class name .card-flipped then the click does nothing because we already have two cards turned over. Otherwise we add the class .card-flipped to the element that has been clicked. And when we have a look at the CSS this is where we will see the transition has been created. Also at the end of this function we start the check to see if the cards match but I’m not going to get into that stuff here.

1.
2.
3.
4.
5.
6.
7.
8.
9.
//if pattern is same remove cards otherwise flip back
function checkPattern() {
 if (isMatchPattern()) {
  $(".card-flipped").removeClass("card-flipped").addClass("card-removed");
  $(".card-removed").bind("webkitTransitionEnd",removeTookCards);
 } else {
  $(".card-flipped").removeClass("card-flipped");
 }
}

So there’s quite a bit going on in this function so firstly we’re checking if the card is matched with the isMatchedpattern function. If it is then we removed the card-flipped class and add the card-removed class which as you will see just reduces the opacity of the div to zero so you can no longer see it. Then we bind the event listener webkitTransitionEnd to say when the div has zero opacity run the removeTookCards function which basically deletes the div.

So now the CSS

So here is where the good stuff happens. Basically the javascript just adds and removes classes when needed and the CSS does the rest.

For each card, we define a perspective property to give it a visual depth effect. We also set the transition property otherwise it’s not a card flip: the card simply toggles between the front and back faces.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
/* Define the 3D perspective view and dimension of each card. */
.card {
 -webkit-perspective: 600;
 width: 109px;
 height: 145px;
 position: absolute;
 -moz-transition: all .3s;
 -webkit-transition: all .3s;
 transition: all .3s;
 cursor: pointer;
}

There are two faces on each card. The face will be rotated later and we will define the transition properties to animate the style changes. We also want to make sure the back face is hidden:

1.
2.
3.
4.
5.
6.
7.
8.
.face {
 width: 100%;
 height: 100%;
 position: absolute;
 -webkit-transition-property: opacity, transform, box-shadow;
 -webkit-transition-duration: .3s;
 -webkit-backface-visibility: hidden;
}

Then we set the front and back face styles. They are almost the same as the flipping card example, except that we are now giving them background images
and box shadows:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
.front {
 background: url(../images/deck.jpg) 0 -146px;
 z-index: 10;
}
.back {
background: #efefef url(../images/deck.jpg);
-webkit-transform: rotate3d(0,1,0,-180deg);
z-index: 8;
}
.card:hover .face, .card-flipped .face {
 -webkit-box-shadow: 0 0 10px #aaa;
}
.card-flipped .front {
 -webkit-transform: rotate3d(0,1,0,180deg);
 z-index: 8;
}
.card-flipped .back {
 -webkit-transform: rotate3d(0,1,0,0deg);
 z-index: 10;
}

When any card is removed, we want to fade it out. Therefore, we declare a card-removed class with 0 opacity:

1.
2.
3.
.card-removed {
 opacity: 0;
}

In order to show different card graphics from the sprite sheet of the card deck, we clip the background of the card into different background positions:

1.
2.
3.
4.
5.
6.
7.
8.
9.
.blueDino {background-position: 0 0;}
.brownDino {background-position: -110px 0;}
.redDino {background-position: -220px 0;}
.greenDino {background-position: -330px 0;}
.purpDino {background-position: -440px 0;}
.burgDino {background-position: -550px 0;}
.orangeDino {background-position: -660px 0;}
.purp2Dino {background-position: -770px 0;}
.pinkDino {background-position: -880px 0;}

And that’s it. If you want to download the code I’ve attached it. Hope you enjoy it and play the game.

View DemoDownload