HTML5 Games Development: Using Local Storage to Store Game Data

Exclusive offer: get 50% off this eBook here
HTML5 Games Development by Example: Beginner’s Guide

HTML5 Games Development by Example: Beginner’s Guide — Save 50%

Create six fun games using the latest HTML5, Canvas, CSS, and JavaScript techniques.

$26.99    $13.50
by Makzan | September 2011 | Beginner's Guides Open Source Web Graphics & Video

Local storage is a new specification from HTML5. It allows a website to store information in the browser locally and access the stored data later. This is a useful feature in game development because we can use it as a memory slot to save any game data locally in a web browser.

In this article by Makzan, author of HTML5 Games Development by Example - Beginner's Guide, we are going to add game data storing to a CSS3 memory matching game. Besides storing and loading the game data, we will also notify the player for breaking a record with a nice 3D ribbon with pure CSS3 styling. Specifically, we will cover the following topics:

  • Storing data by using HTML5 local storage
  • Saving the object in the local storage
  • Notifying players for breaking a new record with a nice ribbon effect
  • Saving the entire game progress

 

(For more resources on this subject, see here.)

 

The following screenshot shows the final result we will create through this article. So, let's get on with it:

HTML5 Games Development Using Local Storage

Storing data by using HTML5 local storage

Imagine now we have published our CSS3 memory matching game (Code Download-Ch:3) and players are trying their best to perform well in the game.

We want to show the players whether they played better or worse than the last time. We will save the latest score and inform players whether they are better or not this time by comparing the scores.

They may feel proud when performing better. This may make them addicted and they may keep trying to get higher scores.

Creating a game over dialog

Before actually saving anything in the local storage, we need a game over screen. Imagine now we are playing the CSS3 memory matching game that we built and we successfully match and remove all cards. Once we finish, a game over screen pops up and shows the time we utilized to complete the game.

Time for action – Creating a game over dialog with the elapsed played time

  1. Open the CSS3 matching game folder as our working directory.
  2. Download a background image from the following URL (we will use it as the background of the pop up):
    http://gamedesign.cc/html5games/popup_bg.jpg
  3. Place the image in the images folder.
  4. Open index.html into any text editor.
  5. We will need a font for the game over pop up. Add the following font embedding CSS into the head section:

    <link href="http://fonts.googleapis.com/css?family=Orbitron:400,
    700" rel="stylesheet" type="text/css" >

  6. Before the game section, we add a div named timer to show the elapsed playing time. In addition, we add a new popup section containing the HTML markup of the pop-up dialog:

    <div id="timer">
    Elapsed time: <span id="elapsed-time">00:00</span>
    </div>
    <section id="game">
    <div id="cards">
    <div class="card">
    <div class="face front"></div>
    <div class="face back"></div>
    </div> <!-- .card -->
    </div> <!-- #cards -->
    </section> <!-- #game -->
    <section id="popup" class="hide">
    <div id="popup-bg">
    </div>
    <div id="popup-box">
    <div id="popup-box-content">
    <h1>You Won!</h1>
    <p>Your Score:</p>
    <p><span class='score'>13</span></p>
    </div>
    </div>
    </section>

  7. We will now move on to the style sheet. As it is just for styling and not related to our logic yet, we can simply copy the matchgame.css file from matching_game_with_game_over in the code example bundle (Ch:3).
  8. It is time to edit the game logic part. Open the html5games.matchgame.js file in an editor.
  9. In the jQuery ready function, we need a variable to store the elapsed time of the game. Then, we create a timer to count the game every second as follows:

    $(function(){
    ...
    // reset the elapsed time to 0.
    matchingGame.elapsedTime = 0;

    // start the timer
    matchingGame.timer = setInterval(countTimer, 1000);
    }

  10. Next, add a countTimer function which will be executed every second. It displays the elapsed seconds in the minute and second format:

    function countTimer()
    {
    matchingGame.elapsedTime++;

    // calculate the minutes and seconds from elapsed time
    var minute = Math.floor(matchingGame.elapsedTime / 60);
    var second = matchingGame.elapsedTime % 60;

    // add padding 0 if minute and second is less then 10
    if (minute < 10) minute = "0" + minute;
    if (second < 10) second = "0" + second;

    // display the elapsed time
    $("#elapsed-time").html(minute+":"+second);
    }

  11. In the removeTookCards function which we wrote earlier, add the following highlighted code that executes the game over logic after removing all cards:

    function removeTookCards()
    {
    $(".card-removed").remove();

    // check if all cards are removed and show game over
    if ($(".card").length == 0)
    {
    gameover();
    }
    }

  12. At last, we create the following gameover function. It stops the counting timer, displays the elapsed time in the game over pop up, and finally shows the pop up:

    function gameover()
    {
    // stop the timer
    clearInterval(matchingGame.timer);

    // set the score in the game over popup
    $(".score").html($("#elapsed-time").html());
    // show the game over popup
    $("#popup").removeClass("hide");
    }

  13. Now, save all files and open the game in a browser. Try finishing the memory matching game and the game over screen will pop up, as shown in the following screenshot:

    HTML5 Games Development Using Local Storage

What just happened?

We have used the CSS3 transition animation to show the game over pop up. We benchmark the score by using the time a player utilized to finish the game.

Saving scores in the browser

Imagine now we are going to display how well the player played the last time. The game over screen includes the elapsed time as the last score alongside the current game score. Players can then see how well they do this time compared to last time.

Time for action – Saving the game score

  1. First, we need to add a few markups in the popup section to display the last score. Add the following HTML in the popup section in index.html:

    <p>
    <small>Last Score: <span class='last-score'>20</span>
    </small>
    </p>

  2. Then, we open the html5games.matchgame.js to modify some game logic in the gameover function.
  3. Add the following highlighted code in the gameover function. It loads the saved score from local storage and displays it as the score last time. Then, save the current score in the local storage:

    function gameover()
    {
    // stop the timer
    clearInterval(matchingGame.timer);

    // display the elapsed time in the game over popup
    $(".score").html($("#elapsed-time"));

    // load the saved last score from local storage
    var lastElapsedTime = localStorage.getItem
    ("last-elapsed-time");

    // convert the elapsed seconds into minute:second format
    // calculate the minutes and seconds from elapsed time
    var minute = Math.floor(lastElapsedTime / 60);
    var second = lastElapsedTime % 60;
    // add padding 0 if minute and second is less then 10
    if (minute < 10) minute = "0" + minute;
    if (second < 10) second = "0" + second;

    // display the last elapsed time in game over popup
    $(".last-score").html(minute+":"+second);

    // save the score into local storage
    localStorage.setItem
    ("last-elapsed-time", matchingGame.elapsedTime);

    // show the game over popup
    $("#popup").removeClass("hide");
    }

  4. It is now time to save all files and test the game in the browser. When you finish the game for the first time, the last score should be 00:00. Then, try to finish the game for the second time. The game over pop up will show the elapsed time you played the last time. The following screenshot shows the game over screen with the current and last score:

    HTML5 Games Development Using Local Storage

What just happened?

We just built a basic scoring system that compares a player's score with his/her last score.

Storing and loading data with local storage

We can store data by using the setItem function from the localStorage object. The following table shows the usage of the function:

localStorage.setItem(key, value);

HTML5 Games Development Using Local Storage

In our example, we save the game elapsed time as the score with the following code by using the key last-elapsed-item:

localStorage.setItem("last-elapsed-time", matchingGame.
elapsedTime);

Complementary to setItem, we get the stored data by using the getItem function in the following way:

localStorage.getItem(key);

The function returns the stored value of the given key. It returns null when trying to get a non-existent key. This can be used to check whether we have stored any data for a specific key.

The local storage saves the string value

The local storage stores data in a key-value pair. The key and value are both strings. If we save numbers, Boolean, or any type other than string, then it will convert the value into a string while saving.

Usually, problems occur when we load a saved value from the local storage. The loaded value is a string regardless of the type we are saving. We need to explicitly parse the value into the correct type before using it.

For example, if we save a floating number into the local storage, we need to use the parseFloat function when loading it. The following code snippet shows how we can use parseFloat to retrieve a stored floating number:

var score = 13.234;

localStorage.setItem("game-score",score);
// result: stored "13.234".

var gameScore = localStorage.getItem("game-score");
// result: get "13.234" into gameScore;

gameScore = parseFloat(gameScore);
// result: 13.234 floating value

In the preceding code snippet, the manipulation may be incorrect if we forget to convert the gameScore from string to float. For instance, if we add the gameScore by 1 without the parseFloat function, the result will be 13.2341 instead of 14.234. So, be sure to convert the value from local storage to its correct type.

Size limitation of local storage
There is a size limitation on the data stored through localStorage for each domain. This size limitation may be slightly different in different browsers. Normally, the size limitation is 5 MB. If the limit is exceeded, then the browser throws a QUOTA_EXCEEDED_ERR exception when setting a key-value into localStorage.

Treating the local storage object as an associated array

Besides using the setItem and getItem functions, we can treat the localStorage object as an associated array and access the stored entries by using square brackets.

For instance, we can replace the following code with the latter version:

Using the setItem and getItem:

localStorage.setItem("last-elapsed-time", elapsedTime);
var lastElapsedTime = localStorage.getItem("last-elapsed-time");

Access localStorage as an array as follows:

localStorage["last-elapsed-time"] = elapsedTime;
var lastElapsedTime = localStorage["last-elapsed-time"];

HTML5 Games Development by Example: Beginner’s Guide Create six fun games using the latest HTML5, Canvas, CSS, and JavaScript techniques.
Published: August 2011
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

 

(For more resources on this subject, see here.)

Saving objects in the local storage

Now, imagine that we are saving not only the score, but also the date and time when the ranking is created. We can either save two separate keys for the score and date time of playing, or pack the two values into one object and store it in the local storage.

We will pack all the game data into one object and store it.

Time for action – Saving the time alongside the score

Carry out the following steps:

  1. First, open the index.html file from our CSS3 memory matching game.
  2. Replace the HTML markup with the last score by the following HTML (it shows both scores and the date time in the game over pop up):

    <p>
    <small>Last Score: <span class='last-score'>20</span><br>
    Saved on: <span class='saved-time'>13/4/2011 3:14pm</span>
    </small>
    </p>

  3. The HTML markup is now ready. We will move on to the game logic. Open the html5games.matchgame.js file in a text editor
  4. We will modify the gameover function. Add the following highlighted code to the gameover function. It gets the current date time when the game ends and packs a formatted date time with elapsed time together into local storage:

    function gameover()
    {
    // stop the timer
    clearInterval(matchingGame.timer);

    // display the elapsed time in the game over popup
    $(".score").html($("#elapsed-time"));

    // load the saved last score and save time from local storage
    var lastScore = localStorage.getItem("last-score");

    // check if there is no any saved record
    lastScoreObj = JSON.parse(lastScore);
    if (lastScoreObj == null)
    {
    // create an empty record if there is no any saved record
    lastScoreObj = {"savedTime": "no record", "score": 0};
    }
    var lastElapsedTime = lastScoreObj.score;

    // convert the elapsed seconds into minute:second format
    // calculate the minutes and seconds from elapsed time
    var minute = Math.floor(lastElapsedTime / 60);
    var second = lastElapsedTime % 60;
    // add padding 0 if minute and second is less then 10
    if (minute < 10) minute = "0" + minute;
    if (second < 10) second = "0" + second;

    // display the last elapsed time in game over popup
    $(".last-score").html(minute+":"+second);

    // display the saved time of last score
    var savedTime = lastScoreObj.savedTime;
    $(".saved-time").html(savedTime);

    // get the current datetime
    var currentTime = new Date();
    var month = currentTime.getMonth() + 1;
    var day = currentTime.getDate();
    var year = currentTime.getFullYear();
    var hours = currentTime.getHours();
    var minutes = currentTime.getMinutes();
    // add padding 0 to minutes
    if (minutes < 10) minutes = "0" + minutes;
    var seconds = currentTime.getSeconds();
    // add padding 0 to seconds
    if (seconds < 10) seconds = "0" + seconds;

    var now = day+"/"+month+"/"+year+"
    "+hours+":"+minutes+":"+seconds;

    //construct the object of datetime and game score
    var obj = { "savedTime": now, "score":
    matchingGame.elapsedTime};

    // save the score into local storage
    localStorage.setItem("last-score", JSON.stringify(obj));

    // show the game over popup
    $("#popup").removeClass("hide");
    }

  5. We will save the files and open the game in a web browser.
  6. When we finish the game for the first time, we will get a screen similar to the following screenshot which will show our game score and state that there are no previous records:

    HTML5 Games Development Using Local Storage

  7. Now try reloading the page and play the game again. When we finish the game for the second time, the game over dialog will show our saved record. The following screenshot shows how it should look:

    HTML5 Games Development Using Local Storage

What just happened?

We have just used a Date object in JavaScript to get the current date and time when the game is over. In addition, we packed the game over date and time and the game elapsed time in one object and saved it into the local storage. The saved object is encoded in a JSON string. It will also load the last saved date and time and the game elapsed time from the storage and parse it back to the JavaScript object from a string.

Getting the current date and time in JavaScript

The Date object in JavaScript is used to working with date and time. When we create an instance from the Date object, by default it stores the current date and time. Therefore, we can easily get the current date and time information by using the following code snippet:

var currentTime = new Date();
var month = currentTime.getMonth() + 1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var hours = currentTime.getHours();
var minutes = currentTime.getMinutes();
var seconds = currentTime.getSeconds();

As we display the date and time in a human-friendly format, we also need to add zero padding to minutes and seconds when they are less than 10. We do this as follows:

if (minutes < 10) minutes = "0" + minutes;
if (seconds < 10) seconds = "0" + seconds;
var now = day+"/"+month+"/"+year+" "+hours+":"+minutes+":"+
seconds;

The following table lists some useful functions in the Date object to get the date and time:

HTML5 Games Development Using Local Storage

The Mozilla Developer Network provides a detailed reference for using the Date object at the following URL:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date

Using the native JSON to encode an object into a string

JSON is an object notation format that is friendly for machines to parse and generate. In this example, we packed the final elapsed time and the date and time into an object. Then, we encoded the object into JSON. Modern web browsers come with a native JSON support. We can easily encode any JavaScript object into JSON by using the stringify function as follows:

JSON.stringify(anyObject);

Normally, we only use the first parameter for the stringify function. It is the object that we are going to encode as a string. The following code snippet demonstrates the result of an encoded JavaScript object:

var jsObj = {};
jsObj.testArray = [1,2,3,4,5];
jsObj.name = 'CSS3 Matching Game';
jsObj.date = '8 May, 2011';
JSON.stringify(jsObj);
// result: {"testArray":[1,2,3,4,5],"name":"CSS3 Matching
Game","date":"8 May, 2011"}

The stringify method can parse objects with data structure into a string well. However, it cannot convert anything from an object into a string. For instance, it will return an error if we try to pass a DOM element into it. It will return the string representing the date if we pass a Date object. Alternatively, it will drop all methods definition of the parsing object.

Loading a stored object from a JSON string

The complete form of JSON is JavaScript Object Notation. From the name, we know that it uses the syntax from JavaScript to represent an object. Therefore, it is very easy to parse a JSON formatted string back to a JavaScript object.

The following code snippet shows how we can use the parse function in the JSON object:

JSON.parse(jsonFormattedString);

We can open the console in the Web Inspector to test the JSON JavaScript functions. The following screenshot shows the running result of the code snippets we just discussed when encoding an object and parsing them:

HTML5 Games Development Using Local Storage

Inspecting the local storage in a console window

After we have saved something in the local storage, we may want to know what is exactly saved before we write the loading part. We can inspect what we have saved by using the storage panel in the Web Inspector. It lists all the saved key-value pairs under the same domain. The following screenshot shows that we have the last-score saved with value {"savedTime":"23/2/2011 19:27:02","score":23}.

The value is the result of the JSON.stringify function we used to encode the object into JSON. You may also try saving an object directly into local storage:

HTML5 Games Development Using Local Storage

Besides localStorage, there are other storage approaches that were not discussed. These approaches include the Web SQL Database (http://www.w3.org/TR/webdatabase/), which uses SQLite to store data, and IndexedDB (https://developer.mozilla.org/en/IndexedDB).

Notifying players of breaking a new record with a nice ribbon effect

Imagine that we want to encourage players by informing them that they broke a new record compared to the last score. We want to show a ribbon with New Record text on it. Thanks to the new CSS3 properties, we can create a ribbon effect completely in CSS.

HTML5 Games Development by Example: Beginner’s Guide Create six fun games using the latest HTML5, Canvas, CSS, and JavaScript techniques.
Published: August 2011
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

 

(For more resources on this subject, see here.)

Time for action – Creating a ribbon in CSS3

We will create a new record ribbon and display it when a player breaks his/her last score. So, carry out the following steps:

  1. First, open index.html where we will add the ribbon HTML markup.
  2. Add the following highlighted HTML right after popup-box and before popup-box-content:

    <div id="popup-box">
    <div class="ribbon hide">
    <div class="ribbon-body">
    <span>New Record</span>
    </div>
    <div class="triangle"></div>
    </div>
    <div id="popup-box-content">
    ...

  3. Next, we need to focus on the style sheet. The entire ribbon effect is done in CSS. Open the matchgame.css file in a text editor
  4. n the popup-box styling, we need to add a relative position to it. We do this as follows:

    #popup-box {
    position: relative;
    ...
    }

  5. Then, we need to add the following styles that create the ribbon effect to the CSS file:

    .ribbon.hide {
    display: none;
    }
    .ribbon {
    float: left;
    position: absolute;
    left: -7px;
    top: 165px;
    z-index: 0;
    font-size: .5em;
    text-transform: uppercase;
    text-align: right;
    }
    .ribbon-body {
    height: 14px;
    background: #ca3d33;
    padding: 6px;
    z-index: 100;
    -webkit-box-shadow: 2px 2px 0 rgba(150,120,70,.4);
    border-radius: 0 5px 5px 0;

    color: #fff;
    text-shadow: 0px 1px 1px rgba(0,0,0,.3);
    }
    .triangle{
    position: relative;
    height: 0px;
    width: 0;
    left: -5px;
    top: -32px;
    border-style: solid;
    border-width: 6px;
    border-color: transparent #882011 transparent transparent;
    z-index: -1;
    }

  6. Lastly, we need to modify the game over logic a little bit. Open the html5games.matchgame.js file and locate the gameover function.
  7. Add the following code to the gameover function which compares the current score with the last score to determine the new record:

    if (lastElapsedTime == 0 || matchingGame.elapsedTime <
    lastElapsedTime)
    {
    $(".ribbon").removeClass("hide");
    }

  8. We will test the game in a web browser. Try finishing a game slowly and then finish another game fast. When you break the last score, the game over pop up shows a nice NEW RECORD ribbon, as shown in the following screenshot:

    HTML5 Games Development Using Local Storage

What just happened?

We have just created a ribbon effect in a pure CSS3 style with some help from JavaScript to show and hide it. The ribbon is composited by a little triangle overlaid by a rectangle, as shown in the following screenshot:

HTML5 Games Development Using Local Storage

Now, how can we create a triangle in CSS? We can create a triangle by setting both width and height to 0 and drawing only one border. The size of the triangle is then decided by the border width. The following code is for the triangle CSS we used in our new record ribbon:

.triangle{
position: relative;
height: 0px;
width: 0;
left: -5px;
top: -32px;
border-style: solid;
border-width: 6px;
border-color: transparent #882011 transparent transparent;
z-index: -1;
}

The following PVM Garage website provides a detailed explanation on pure CSS3 ribbon usage:
http://www.pvmgarage.com/2010/01/how-to-create-depth-and-nice-3d-ribbons-only-using-css3/

Have a go hero – Saving and comparing only to the fastest time

Each time the game finishes, it compares the last score with the current score. Then, it saves the current score.

How about changing the code to save the highest score and show the new record ribbon when breaking the highest score?

Saving the entire game progress

We have enhanced our CSS3 memory matching game by adding a game over screen and storing the game record. Imagine now that a player is in the mid game and accidentally closes the web browser. Once the player opens the game again, the game starts from the beginning and the game that the player was playing is lost. With the local storage, we can encode the entire game data into JSON and store them. In this way, players can resume their game later.

Saving the game progress

We are going to pack the game data into one object and save it into the local storage every second.

Time for action – Saving all essential game data in the local storage

We will continue work with our CSS3 memory matching game:

  1. Open the html5games.matchgame.js JavaScript file.
  2. Add the following code at the top of the JavaScript file after declaring the matchingGame variable. This code creates an object named savingObject to save the array of deck and removed cards and the current elapsed time:

    matchingGame.savingObject = {};

    matchingGame.savingObject.deck = [];

    // an array to store which card is removed by storing their
    index.
    matchingGame.savingObject.removedCards = [];

    // store the counting elapsed time.
    matchingGame.savingObject.currentElapsedTime = 0;

  3. In the jQuery function, add the following highlighted code. It clones the order of the deck to the savingObject. In addition, it assigns an index to each card in the DOM data attribute:

    $(function(){
    // shuffling the deck
    matchingGame.deck.sort(shuffle);

    // copying the deck into saving object.
    matchingGame.savingObject.deck = matchingGame.deck.slice();

    // clone 12 copies of the card DOM
    for(var i=0;i<11;i++){
    $(".card:first-child").clone().appendTo("#cards");
    }
    ...
    // embed the pattern data into the DOM element.
    $(this).attr("data-pattern",pattern);
    // save the index into the DOM element, so we know which is the
    next card.
    $(this).attr("data-card-index",index);
    ...

  4. We have a countTimer function that executes every second. We add the following highlighted code in the countTimer function. It saves the current elapsed time in the savingObject and also saves the object in the local storage:

    function countTimer()
    {
    matchingGame.elapsedTime++;

    // save the current elapsed time into savingObject.
    matchingGame.savingObject.currentElapsedTime =
    matchingGame.elapsedTime;
    ...
    // save the game progress
    saveSavingObject();
    }

  5. The game removes cards when the player finds a matching pair. We replace the original $(".card-removed").remove(); code with the following highlighted code in the removeTookCards function. It remembers which cards are removed in the savingObject:

    function removeTookCards()
    {
    // add each removed card into the array which store which
    cards are removed
    $(".card-removed").each(function(){
    matchingGame.savingObject.removedCards.push
    ($(this).data("card-index"));
    $(this).remove();
    });

    // check if all cards are removed and show game over
    if ($(".card").length == 0)
    {
    gameover();
    }
    }

  6. We have to remove the saved game data in the local storage when the game is over. Add the following code in the gameover function:

    {

    //at last, we clear the saved savingObject
    localStorage.removeItem("savingObject");
    }

  7. At last, we have a function to save the savingObject in the local storage:

    function saveSavingObject()
    {
    // save the encoded saving object into local storage
    localStorage["savingObject"] =
    JSON.stringify(matchingGame.savingObject);
    }

  8. We have modified the code a lot and it is now time to test the game in a web browser. After the game runs, try clearing several matching cards. Then, open the storage panel in the Web Inspector. The local storage should contain an entry similar to the one shown in the following screenshot. It is a record with a key savingObject and a value with a long string in a JSON format. The JSON string contains the shuffled deck, removed cards, and the current elapsed time:

What just happened?

We have just entered all essential game data into an object named savingObject. This savingObject contains all information that we need to recreate the game later. It includes the order of cards, removed cards, and the current elapsed time.

Lastly, we saved savingObject in localStorage on each second. The object is encoded into JSON using the stringify function we used earlier in this article. Then, we recreated the game by parsing the JSON string from the local storage.

Removing a record from the local storage

We need to remove the saved record when the game is over. Otherwise, the new game will not start. Local storage provides a remoteItem function to remove a specific record.

Here is how we use the function to remove the record with the given key:

localStorage.removeItem(key);

If you want to remove all stored records, then you can use the localStorage.clear() function.

Cloning an array in JavaScript

We cloned the shuffled deck in savingObject, so that we could use the order of the deck to recreate the cards when we resumed the game. However, we cannot copy an array by assigning the array to another variable. The following code fails to copy an array A to array B:

var a = [1,2,3,4,5];
var b = a;
a.pop();
// result:
// a: [1,2,3,4]
// b: [1,2,3,4]

The slice function provides an easy way to clone an array with only primitive types of elements. We can clone an array with the slice function as long as it does not contain another array or object as an element. The following code successfully clones an array A to B:

var a = [1,2,3,4,5];
var b = a.slice();
a.pop();
// result:
// a: [1,2,3,4]
// b: [1,2,3,4,5]

The slice function is normally used to create a new array by selecting a range of elements from an existing array. When using the slice function without any arguments, it clones the entire array. The Mozilla Developer Network provides a detailed usage on the slice function at the following URL:

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/slice

Resuming the game progress

We have saved the game progress, but have not yet written the logic for resuming the game. So, let's move on to the resuming part.

Time for action – Resuming a game from the local storage

Carry out the following steps:

  1. Open the html5games.matchgame.js JavaScript file.
  2. In the jQuery ready function, we used the saved order of deck in the previous game instead of shuffling a new deck. Add the following highlighted code into the ready function:

    $(function(){
    // shuffling the deck
    matchingGame.deck.sort(shuffle);

    // re-create the saved deck
    var savedObject = savedSavingObject();
    if (savedObject != undefined)
    {
    matchingGame.deck = savedObject.deck;
    }
    ...

  3. After initializing the cards in the ready function, we remove cards which were removed in the previous game. We also restore the saved elapsed time from the saved value. Add the following highlighted code in the jQuery ready function:

    // removed cards that were removed in savedObject.
    if (savedObject != undefined)
    {
    matchingGame.savingObject.removedCards =
    savedObject.removedCards;
    // find those cards and remove them.
    for(var i in matchingGame.savingObject.removedCards)
    {
    $(".card[data-card-index="+matchingGame.savingObject.
    removedCards[i]+"]").remove();
    }
    }
    // reset the elapsed time to 0.
    matchingGame.elapsedTime = 0;
    // restore the saved elapsed time
    if (savedObject != undefined)
    {
    matchingGame.elapsedTime = savedObject.currentElapsedTime;
    matchingGame.savingObject.currentElapsedTime = savedObject.
    currentElapsedTime;
    }

  4. Finally, we create the following function to retrieve savingObject from the local storage:

    // Returns the saved savingObject from the local storage.
    function savedSavingObject()
    {
    // returns the saved saving object from local storage
    var savingObject = localStorage["savingObject"];
    if (savingObject != undefined)
    {
    savingObject = JSON.parse(savingObject);
    }
    return savingObject;
    }

  5. Save all files and open the game in web a browser. Try playing the game by removing several matching cards. Then, close the browser window and open the game again. The game should resume from the state where we closed the window, as shown in the following screenshot:

    HTML5 Games Development Using Local Storage

What just happened?

We just finished the game loading part by parsing the saved JSON string of the entire game status.

Then, we restored the elapsed time and order of deck from the loaded savingObject. Restoring these two properties is simply variable assigning. The tricky part is recreating the card removing. In the game saving section, we assigned an index to each card DOM by custom data attribute data-card-index. We stored the index of each removed card when saving the game, so we can know which cards are removed when loading the game. Then, we can remove those cards when the game sets up. The following code removes the cards in a jQuery game ready function:

if (savedObject != undefined)
{
matchingGame.savingObject.removedCards = savedObject.
removedCards;
// find those cards and remove them.
for(var i in matchingGame.savingObject.removedCards)
{
$(".card[data-card-index="+matchingGame.savingObject.
removedCards[i]+"]").remove();
}
}

Tracking the storage changes with the storage event
Sometimes, we may want to listen to the changes of the localStorage. We can do that by listening to the storage event. It is fired when anything is changed in the localStorage. The following link from Dive into HTML5 provides a detailed discussion on how we can use the event:
http://diveintohtml5.org/storage.html#storage-event

Summary

We learned a lot in this article about using the local storage to save the game data in a web browser.

Specifically, we covered:

  • Saving and retrieving basic data into the key-value pair local storage
  • Encoding an object into the JSON formatted string and parsing the string back to a JavaScript object
  • Saving the entire game progress, so the game can resume even if left mid way

We also created a nice 3D ribbon as a new record badge in pure CSS3 styling.


Further resources on this subject:


About the Author :


Makzan

Makzan is the founder of 42games limited (http://42games.net). He began building apps and games on the Web when he was a child. He built iOS games that have ranked No.1 on the App Store as well as demos on the Apple store. He now focuses on teaching programming.

Makzan has also written two books named Flash Multiplayer Virtual World and HTML5 Games Development Beginner’s Guide.

I would like to thank the whole team from Packt Publishing. The video series will not be possible without the help from all the editors. I thank all reviewers for providing very useful comments from which I have learnt a lot. I thank my family for giving me support during the process.

Books From Packt


HTML5 Multimedia Development Cookbook
HTML5 Multimedia Development Cookbook

HTML5 Canvas Cookbook: RAW
HTML5 Canvas Cookbook: RAW

Dreamweaver CS5.5 Mobile and Web Development with HTML5, CSS3, and jQuery
Dreamweaver CS5.5 Mobile and Web Development with HTML5, CSS3, and jQuery

HTML5 Mobile Development Cookbook
HTML5 Mobile Development Cookbook

Unity 3 Game Development Hotshot
Unity 3 Game Development Hotshot

Unity 3.x Game Development Essentials
Unity 3.x Game Development Essentials

Away3D 3.6 Cookbook
Away3D 3.6 Cookbook

Panda3D 1.6 Game Engine Beginner's Guide
Panda3D 1.6 Game Engine Beginner's Guide


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
F
q
m
y
a
S
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software