Creating the game engine using jQuery
First, we declare a function which will create the initial conditions for the game flow:
|
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 |
function startGame() { var matchingGame = {}; matchingGame.deck = [ "cardAK", "cardAQ", "cardBQ", "cardA9", "cardB9", "cardC9", "cardAQ", "cardBK", "cardBJ", "cardA9", "cardB9", "cardC9", "cardAJ", "cardAJ", "cardBQ", "cardA10", "cardB10", "cardC10", "cardB10", "cardA10", "cardC10", "cardBJ", "cardBK", "cardAK", ]; function shuffle() { return 0.5 - Math.random(); }; matchingGame.deck.sort(shuffle); for (var i=0;i<23;i++) { $(".card:first-child").clone().appendTo("#cards") }; //initialize each card position $("#cards").children(".card").each(function(index) { //align the cards to be 6x4 ourselves $(this).css({ "left" : ($(this).width() + 10) * (index % 6), "top" : ($(this).height() + 10) * Math.floor(index/6) }); //get a pattern from the shuffled deck var pattern = $(matchingGame.deck).get(); $(this).find(".back").addClass(pattern[index]); $(this).attr("data-pattern", pattern[index]); $(this).click(selectCard); }); }; |
Firstly we declare the deck of paired cards in the array matchingGame.deck, for this example being 12 pairs. After this, the elements of the array are randomly arranged. The next step is to clone the first child of the element with the class “card” and append the new created elements to the element with the ID “card”. Doing this we’ll have the containers for all 24 cards, containers that will be positioned inside the box with the ID “cards”, based on their width and height and their position inside the matchingGame.deck array. At the same time a class is added to the elements with class “back”, class that holds the name of each paired elements. If a card is clicked, the selectCard() function is called:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function selectCard() { // we do nothing if there are already two cards flipped. if ($(".card-flipped").size() > 1) { return; } if ($(this).hasClass("card-flipped") == false) { update($("#clicks")); }; $(this).addClass("card-flipped"); // check the pattern of both flipped card 0.5s later. if ($(".card-flipped").size() == 2) { setTimeout(checkPattern,500); } }; |
This function checks if one or two cards are flipped and based on this criteria performs some actions. Another check is made to avoid more than one click of a card, and the number of clicks made to be accurate.
If two cards are flipped the checkPattern() functions is called:
|
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 |
function checkPattern() { if (isMatchPattern()) { $(".card-flipped").removeClass("card-flipped").addClass("card-removed"); $(".card-removed").bind("fadeOut", removeTookCards); } else { $(".card-flipped").removeClass("card-flipped"); } if ($("#cards").children().length == $("#cards").children(".card-removed").length) { $("#go-2-nxt-lvl").html("<p>Game Finished!<br /> Click OK to restart the game.<br /><button id='reload'>OK</button></p>").fadeIn(1200); $("#reload").on("click", function() { $("#go-2-nxt-lvl").fadeOut(500); setTimeout(function(){ $(".card:first-child").addClass("first").removeClass("card-removed"); $(".card").not(".first").remove(); $(".first").html(); startGame() },400); }); } }; function isMatchPattern() { var cards = Array(); $(".card-flipped").each(function() { cards.push($(this).attr("data-pattern")); }); return (cards[0] == cards[1]); }; |
The checkPattern() function performs some actions if two cards flipped are identical. If two cards are identical they are removed (hide) from the user’s view, otherwise they are flipped back. In the case that all cards are removed a message is displayed to replay the game and the HTML elements manipulated during the game flow are reset to a new state (children of the element with the class “card” are removed). This new state should be checked next time the game starts and the elements with the classes “face front” and “face back” should be recreated. To do this the following lines of code are added to the startGame() function:
|
1 2 3 4 |
if ($(".card:first-child").hasClass("first")) { $(".card:first-child").removeClass("first"); $(".card:first-child").html('<div class="face front"></div><div class="face back"></div>'); }; |
Each time the checkPattern() function is called the matched pairs value should be updated accordingly:
|
1 2 3 4 |
var pairs = Math.floor($(".card-removed").length/2); if ($("#pairs").text() != pairs) { $("#pairs").text(pairs); } |
Having this set, the game can be played from now.
A new game version released on April 17th 2012
This new version uses 12 pairs of cards taken (somehow randomly) from a deck of 52 cards. With this approach the game flow is not as flat as in previous version.
The modified code:
|
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 32 33 34 35 36 37 38 39 40 |
//initialize all cards var allCards = [ "cardAA", "cardA2", "cardA3", "cardA4", "cardA5", "cardA6", "cardA7", "cardA8", "cardA9", "cardA10", "cardAJ", "cardAQ", "cardAK", "cardBA", "cardB2", "cardB3", "cardB4", "cardB5", "cardB6", "cardB7", "cardB8", "cardB9", "cardB10", "cardBJ", "cardBQ", "cardBK", "cardCA", "cardC2", "cardC3", "cardC4", "cardC5", "cardC6", "cardC7", "cardC8", "cardC9", "cardC10", "cardCJ", "cardCQ", "cardCK", "cardDA", "cardD2", "cardD3", "cardD4", "cardD5", "cardD6", "cardD7", "cardD8", "cardD9", "cardD10", "cardDJ", "cardDQ", "cardDK" ]; //initialize game engine function startGame() { var matchingGame = {}; //get the first 12 cards from the entire deck after the suffle matchingGame = allCards.sort(shuffle).slice(0,12); //merge the cards to have pairs matchingGame.deck = $.merge(matchingGame, matchingGame); if ($(".card:first-child").hasClass("first")) { $(".card:first-child").removeClass("first"); $(".card:first-child").html('<div class="face front"></div><div class="face back"></div>'); }; $("#clicks, #pairs").text("0"); function shuffle() { return 0.5 - Math.random(); }; matchingGame.deck.sort(shuffle); for (var i=0;i<23;i++) { $(".card:first-child").clone().appendTo("#cards") }; //initialize each card position $("#cards").children(".card").each(function(index) { //align the cards to be 6x4 ourselves $(this).css({ "left" : ($(this).width() + 10) * (index % 6), "top" : ($(this).height() + 10) * Math.floor(index/6) }); //get a pattern from the shuffled deck var pattern = $(matchingGame.deck).get(); $(this).find(".back").addClass(pattern[index]); $(this).attr("data-pattern", pattern[index]); $(this).click(selectCard); }); }; |





