# Chapter 7, Exercise 4 – Saving Level Stars

Once you’ve added the preceding star system, create a way to store the number of stars the player has obtained for each level. Then you can show them not only how many stars they’ve attained but also a message when they beat a previous best. Currently, we store the number of bubbles remaining, the player’s score, and current level number as variables inside Game. But now the best approach might be to create an object that stores each level and records the number of stars. Save this data to Local Storage for when the player returns to the game.

We can build on Exercise 3 to keep track of stars achieved. Firstly, we’re going to create an array that stores the number of stars a player has achieve for each level. We can then load this at start time and then save it when the player completes a level.

First, we’ll add another element to the end_game dialog:

<div id="end_game" class="dialog">
<div id="end_game_message">
<h2>Game Over</h2>
<div id="final_score">
<span>Final Score:</span>
<span id="final_score_value"></span>
</div>
<div id="best_stars">
New Best Star Award!!!
</div>
<div id="stars">
</div>
<div id="new_high_score">New High Score!</div>
<div id="level_failed" class="level_failed">Level Failed!</div>
<div id="level_complete" class="level_complete">Level Complete!</div>
</div>
<div class="but_start_game button">
<span class="level_complete">Next Level</span>
<span class="level_failed">New Game</span>
</div>
</div>

Then at the top of game.js, we’ll keep track of the player’s star count, and in the init method we’ll load any previous stars achieve from Local Storage:

var Game = function(){
var curBubble;
var board;
var numBubbles;
var bubbles = [];
var MAX_BUBBLES = 70;
var POINTS_PER_BUBBLE = 50;
var level = 0;
var score = 0;
var highScore = 0;
var requestAnimationID;
var MAX_ROWS = 11;
var stars = [];
this.init = function(){
if(BubbleShoot.Renderer){
BubbleShoot.Renderer.init(function(){
\$(".but_start_game").click("click",startGame);
});
}else{
\$(".but_start_game").click("click",startGame);
};
if(window.localStorage && localStorage.getItem("high_score")){
highScore = parseInt(localStorage.getItem("high_score"));
}
if(window.localStorage && localStorage.getItem("stars")){
stars = JSON.parse(localStorage.getItem("stars"));
}
BubbleShoot.ui.drawHighScore(highScore);
};
…
};

Finally, in endGame also in game.js, we’ll display the message to the player if they beat their previous star total for the level, and then save the new value to Local Storage:

var endGame = function(hasWon){
var numStars = 0;
var startingBubbles = MAX_BUBBLES - level * 5;
var percentRemaining = numBubbles/startingBubbles * 100;
if(percentRemaining > 50){
numStars = 3;
}else if(percentRemaining > 25){
numStars = 2;
}else if(hasWon){
numStars = 1;
}
if(!stars[level] || numStars > stars[numStars]){
stars[level] = numStars
localStorage.setItem("stars",JSON.stringify(stars));
\$('#best_stars').show();
}else{
\$('#best_stars').hide();
}
if(score > highScore){
highScore = score;
\$("#new_high_score").show();
BubbleShoot.ui.drawHighScore(highScore);
if(window.localStorage){
localStorage.setItem("high_score",highScore);
}
}else{
\$("#new_high_score").hide();
};
if(hasWon){
level++;
}else{
score = 0;
level = 0;
};
\$(".but_start_game").click("click",startGame);
\$("#board .bubble").remove();
BubbleShoot.ui.endGame(hasWon,score,numStars);
};

Again, the message could be improved with some styling, but the first time you beat a level you should see a message telling you that you have a “New Best Star Award”. Previous awards are stored as an Array JSON encoded as a string in Local Storage, which you can see if you type:

localStorage.getItem('stars')

into the JavaScript console once you’ve completed a level.