Advertisement

Accessing the Same Saved Data With Separate Flash and JavaScript Apps

by

In this tutorial I will show you how to access the same saved data in separate Flash and JavaScript apps, by storing it in HTML5 LocalStorage and using ExternalInterface to reach it with AS3. We will create the same app in both JavaScript and Flash to demonstrate that it is platform agnostic.


Step 1: Examining Local Storage

Local Storage is an exciting part of HTML5 that allows you to do browser side storage that is persistent, meaning it lasts between browser sessions. It only disappears when the user clears their browser cache.

It is a very easy API to use, using simple key-value pairs to store data, and can be used in a few different ways. One way is to use localStorage.setItem('key','value'), and localStorage.getItem('key'). Another way is to use Object Notation: localStorage[key] = value to set a value, and theValue = localStorage[key] to retrieve it. And, if that wasn't enough, there is yet a third way - Dot Notation: localStorage.key = value to set it, and theValue = localStorage.key to retrieve it.

I am opting for the third way in this tutorial, but if you prefer one of the other ways you can modify the code and it should work just fine. Local Storage does have a few other methods, but these are the only two methods we need: one to set a value and one to retrieve that value.


Step 2: Setting Up the JavaScript Project

We will create the JavaScript app first. You should develop both this and the Flash project on a live server, otherwise you will run into problems. I am using WAMP on my machine as a local hosting environment.

Create a folder to store your project in. Within this folder create two new folders. Name one of them "js" and the other "styles".

Within the "styles" folder create a new file and name it "style.css", and within the "js" folder create a new file and name it "externalinterface.js". Finally, at the root of your project folder create a new file and name it "index.html".


Step 3: The Index HTML Page

Enter the following code within the "index.html" file you created in the step above.

<!DOCTYPE html>
<html>
<head>
<title>Local Storage with external Interface</title>
<link rel="stylesheet" type="text/css" href="styles/style.css" />
<script type="text/javascript" src="js/externalinterface.js"></script>
</head>
<body>
<div id="wrapper">
<div id="scorewrapper">
<p id="scorediv"></p>


<p id="randomscorediv">Random Score is: </p>


<button type="button" id="scorebtn">Generate Score</button> 
</div>


</div>


</body>
</html>

Here we set up the structure of our "index.html" file. We include the "style.css" and the "externalinterface.js" we created in the step above. The scorediv will be updated when we achieve a new high score, and the randomscorediv will be updated each time we generate a new score (click on the button to generate a random score).


Step 4: style.css

Enter the following within the "style.css" you created in the step above.

#wrapper{
	width:400px;
	height:400px;
	margin: 0 auto;
	
	
}
#scorewrapper{
	width:400px;
	height:200px;
	background-color:#FFFFFF;
}

#randomscorediv{
	visibility: hidden;
}

body{
	background: #f2f2f2;  
	text-align: center; 
	padding: 20px;
}

Here we set the app to be centered in the page, set the background-color of the scorewrapper div, and set the randomscorediv to initially be hidden (invisible). When we click on the button we will set the randomscorediv to visible.


Step 5: window.onload

Enter the following code within the "externalinterface.js" you created in the step above.

window.onload = function(){
alert("Window Loaded");
}

Whenever you need to tie into elements on your web page you should make sure the window has loaded first. Since we need to tie into the button, we use the window.onload function provided by JavaScript. Here we are just popping up an alert with the words "Window Loaded". If you test the page you should see it is working.


Step 6: setScore()

In this step we will code the setScore() function that initially sets the score to 0. Enter the following code within the "externalinterface.js".

window.onload = function(){
	function setScore(){
		if(!localStorage.score){
			localStorage.score = 0;
		}
	}
}

Here we check whether the localStorage.score exists, and if it doesn't we initialise its value to 0. When the user first runs the app, or after they clear their cache, this value would not exist - so we need to create it.

Now call this function immediately after you create it, and test by putting it in an alert.

window.onload = function(){
	function setScore(){
		if(!localStorage.score){
			localStorage.score = 0;
		}
	}
	setScore();
	alert(localStorage.score);
}

Step 7: getScore()

We have a way to set our score, now we need a way to retrieve it. That is what the getScore() function will accomplish. Enter the following beneath the setScore() function you created in the step above.

function getScore(){
	if(localStorage.score){
		return(localStorage.score);
	}
}

Here we check that localStorage.score does exist, and if it does we simply return the value it holds. Remove the alert from the previous step, and add the following alert beneath the getScore() function.

function getScore(){
	if(localStorage.score){
		return(localStorage.score);
	}
}
alert(getScore());
}

If you test now you should see the alert again showing the score of "0".


Step 8: updateScore()

Now that we have a way to set and get our score, we need a way to update it. That is exactly what the updateScore() function achieves. Add the following beneath the getScore() function you created in the step above.

function updateScore(newScore){
	if(localStorage.score){
		localStorage.score = newScore
	}
}

Here we pass as a parameter a newScore; we then set the localStorage.score equal to this value. Remove the alert from the previous step, then add the following beneath the updateScore() function you just created.

function updateScore(newScore){
	if(localStorage.score){
		localStorage.score = newScore;
	}
}
updateScore(10);
alert(getScore());

If you test now, you should see "10" being alerted, since on line 6 we updated the score to 10.


Step 9: showScore()

Now that we have all our methods in place to manipulate the score, let's get it showing. Enter the following beneath the updateScore() function you created in the step above.

function showScore(){
    var scoreText = document.getElementById('scorediv');
    scoreText.innerHTML = "Current High Score is "+getScore();
}

Here we get a reference to the scorediv, and alter its innerHTML property to show the current score.

Call this function immediately after you create it.

function showScore(){
    var scoreText = document.getElementById('scorediv');
    scoreText.innerHTML = "Current High Score is "+getScore();
}
showScore();

If you test the page now you should see the words "Current High Score is 10".


Step 10: Getting a Reference to the Button

We want to run a function when the user click on the button. Add the following beneath the showScore() button you created in the step above.

var scoreBtn = document.getElementById('scorebtn');
scoreBtn.addEventListener('click',getRandomScore,false);

Here we get a reference to the button which we gave the ID scorebtn. We then add an EventListener of type click, which calls the getRandomScore() function that we will create in the next step.


Step 11: getRandomScore()

The getRandomScore() function is where the logic of this application takes place. Add the following beneath the line scoreBtn.addEventListener('click',getRandomScore,false); you entered in the step above.

function getRandomScore(){
	var randScoreText = document.getElementById('randomscorediv');
	randScoreText.style.visibility='visible';
	var randScore = Math.floor(Math.random()* 200000);
	var currentScore = Number(getScore());
	randScoreText.innerHTML = "Random Score is "+randScore;
	if(randScore > currentScore){
		alert("New High Score!!");
		updateScore(randScore);
		showScore();
	}
}

Here, we first get a reference to the randomscorediv and set it to be visible. We then generate a random score by calling Math.floor(Math.random()* 200000), which creates a number between 0 and 200,000. We use our getScore() function to set the variable currentScore (making sure we cast it to a Number), and set the innerHTML of the randScoreText to the randScore.

Lastly we check whether randScore is greater than currentScore, and if it is we show an alert("New High Score!!") and then update the localStorage.score by calling our updateScore() method and passing in the randomScore. We then use showScore() to show the new score.

This concludes the JavaScript application - you can test it here. In the next step we will start devloping the Flash version.


Step 12: Setting Up the Flash Project

In this step we will set up the Flash project.

Create a folder to store your project files in. Now inside this folder create a folder named "js", and within this folder create a file and name it "externalinterface.js". At the root of your project folder create a file named "index.html". Lastly, create a new Flash Project and save it in the root folder, making sure you name it "externalInterface.fla". Give it a white background, and set the size to 400x200px.


Step 13: Setting Up the Index Page

Add the following to the "index.html" file you created in the step above.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tuts+ Premium: Demo</title>
<style>
	body {background: #f2f2f2;  text-align: center; padding: 20px}
</style>
<script type="text/javascript" src="js/externalinterface.js"></script>
</head>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="400" height="200" id="externalInterface" align="middle">  
  <param name="allowScriptAccess" value="sameDomain" />  
  <param name="allowFullScreen" value="false" />  
  <param name="movie" value="externalInterface.swf" />  
  <param name="quality" value="high" />  
  <param name="bgcolor" value="#ffffff" />  
  <embed src="externalInterface.swf" quality="high" bgcolor="#ffffff" width="400" height="200" name="externalInterface" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />  
</object>  
</body>
</html>

Here we set up our "index.html" file. We include the "externalinterface.js" we created in the step above, and embed the SWF file inside the object tag. If you decided to name your FLA something different, it is important to place the correct value for the SWF where applicable.


Step 14: Setting Up externalinterface.js

Add the following to the "externalinterface.js" you created in the step above.

function setScore(){
    if(!localStorage.score){
		localStorage.score = 0;
	}
}

function getScore(){
	if(localStorage.score){
	 return localStorage.score;
	 
	}
}

function updateScore(newScore){
		localStorage.score = newScore
	}

These are the same functions we used in the JavaScript application, so I will not be explaining them here. It is important to note that I removed the window.onload, however.


Step 15: Setting Up the FLA

In this step we will setup the UI for the FLA you created in the steps above.

Select the Text tool and make sure the following properties are set under the "Character" panel.

  • Color: black
  • Size: 16pt

Now drag a TextField out to the stage and give it the following properties.

  • X: 102.00
  • Y: 14.00
  • W: 210.00
  • H: 25.25

Give it the instance name "currentScore_txt" and make sure the type is set to "Classic Text" and "Dynamic Text" respectively.

Now, drag another TextField onto the stage and give it the following properties.

  • X: 102.00
  • Y: 49.00
  • W: 210.00
  • H: 25.25

Give it the instance name "randomScore_text".

Go to the Components panel, and drag a button onto the stage. (You can get to the Components panel by going to Window > Components or just by pressing CTRL + F7.)

Give the button the following properties.

  • X: 150.00
  • Y: 110.00
  • W: 100.00
  • H: 22.00

Give it the instance name "scorebtn".

Within the "Components Parameters" panel, change the label to "Generate Score".

Select the Rectangle tool and give it a fill color of "#CCCCCC" and no stroke.

Now, drag a rectangle out on the stage. Click to select the rectangle and give it the following properties.

  • X: 118.00
  • Y: 50.00
  • W: 173.00
  • H: 82.00

Now, right-click on the rectangle and choose "Convert To Symbol"; give it the name "alertBox".

Double click on the rectangle to go into editing mode. Open the Components panel and drag a Button into this MovieClip. Give the Button the following properties.

  • X: 37.00
  • Y: 52.00
  • W: 100.00
  • H: 22.00

Give it the instance name "alertBox_btn", and change the label to read "OK".

Drag a TextField into the MovieClip and give it the following properties.

  • X: 29.00
  • Y: 10.00
  • W: 131.00
  • H: 22.00

Type the words "New High Score!!" into the TextField, then close this MovieClip.


Step 16: Main.as

Create a new ActionScript file and save it as "Main.as". Then, back in your FLA, set Main to be the Document Class.


Step 17: Package and Imports

Add the following within the "Main.as" file you created in the step above.

package  {
	import flash.display.Sprite;
	import flash.events.*;
	import flash.external.ExternalInterface;
	
	public class Main extends Sprite {

		public function Main() {
			
		}
	}
}

Here we import the classes we will need, and code our constructor function.


Step 18: ADDED_TO_STAGE

Add the following within Main().

public function Main() {
	addEventListener(Event.ADDED_TO_STAGE,setup);
}

The ADDED_TO_STAGE event runs when the movie has fully loaded. Here it calls a setup function, which we will create next.


Step 19: The setup() Function

Add the following beneath the Main() constructor function.

private function setup(e:Event):void{
	trace("MOVIE READY");  
}

If you test now you'll see that "MOVIE READY" is traced in the output panel.


Step 20: Hiding the Alert Box

You may have noticed the Alert Box we created was showing when the movie first starts; let's hide it. Enter the following within the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
}

Here we set the alertbox to not be visible. Go ahead and test the movie.


Step 21: setScore()

In this step we will use the External Interface class to call our setScore() function that we set up in the JavaScript code. Enter the following beneath the setup() function you created in the steps above.

private function setScore():void {
    ExternalInterface.call("setScore");
}

Here we use the call() method of the ExternalInterface class to run the setScore() function that is in our JavaScript code. The call() method takes as a parameter the name of the JavaScript function to run (as a string). If we had parameters in our setScore() function, we would have included them here too.

We want this function to run when the movie first starts, so add it to the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
	setScore();
}

Step 22: getScore()

In this step we will get the score to show in our Flash movie. The JavaScript will be sending the score to Flash, and to do this we will use the External Interface method addCallback() to make the function accessible to it.

Add the following within the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
	setScore();
	ExternalInterface.addCallback("getScore", getScore);
}

The addCallback takes two parameters: the name of a function that you want to make accessible via JavaScript (as a string), and an AS3 function that this call will be linked to (as an AS3 function callback). Here we want to make the AS3 getScore() function available to our JavaScript code first; for simplicity's sake we give it the name getScore() when accessed via JavaScript as well.

We will now code this getScore() AS3 function. Add the following beneath the setScore() function you created in the step above.

private function getScore(score:String):int{
	var theScore:int = int(score);
	return theScore;
}

Here we set up our getScore() function. Since we will be receiving a string back from the JavaScript, we set the parameter as a string, and we return an integer. Inside this function we set up a variable named theScore and cast it to an int; we then return theScore.


Step 23: showScore()

In this step we make the current score display in the Flash movie. Enter the following beneath the getScore() function you created in the step above.

private function showScore():void{
	currentScore_txt.text = "Current High Score is: "+ExternalInterface.call("getScore");
}

Here we set the currentScore_txt.text to display the current score. We use ExternalInterface.call("getScore") to call the getScore function in the JavaScript code, which in turn triggers the getScore() function in our ActionScript code. Remember, this returns the score.

Now add the following within the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
	ExternalInterface.addCallback("getScore", getScore);
	setScore();
	showScore();
}

If you test the movie now, you should see the score being shown.


Step 24: addButtonListeners()

We need a way to add some listeners to our buttons, so that when the user clicks on them they do something. Add the following beneath the showScore() method you created in the step above.

private function addButtonListeners():void{
	scorebtn.addEventListener(MouseEvent.CLICK,getRandomScore);
	alertBox.alertBox_btn.addEventListener(MouseEvent.CLICK,hideAlertBox);
}

Add the following highlighted line within the setup() function.

private function setup(e:Event):void{
	alertBox.visible = false;
	setScore();
	ExternalInterface.addCallback("getScore", getScore);
	showScore();
	addButtonListeners();
}

Here we set up our scorebtn to call an AS3 function named getRandomScore(), and we set up the alertBox_btn that is within the alertBox to call an AS3 function named hideAlertBox(). Next we will add these functions.

Add the following beneath the addButtonListeners() function you just created.

private function getRandomScore(e:MouseEvent):void{
	
}
		
private function hideAlertBox(e:Event):void{
	alertBox.visible = false;
}

We will finish the getRandomScore() function in the next step. All we do in the hideAlertBox() function is set the alertBox to not be visible. We will be making it visible when the user gets a new high score.


Step 25: getRandomScore()

In this step we will code the getRandomScore() function, where - just like in the JavaScript application we made - all the app's logic takes place. Add the following within the getRandomScore() body you created in the step above.

private function getRandomScore(e:MouseEvent):void{
	var randScore:int = Math.floor(Math.random()* 200000);
	var currentScore:int = ExternalInterface.call("getScore");
	randomScore_text.text = "Random Score is: "+ randScore.toString();
		if(randScore > currentScore){
		alertBox.visible = true;
		ExternalInterface.call("updateScore",randScore);
		showScore();
	}
}

This works in a very similar way to the JavaScript version. We first generate a number between 0 and 200,000. Then we get the current score by using ExternalInterface.call("getScore"). We set randomScore_text to read out the random score. Lastly we check whether randScore is greater than currentScore, and if it is we show the Alert Box, update the score in Local Storage by using ExternalInterface.call("updateScore",randScore), and call our showScore() method to show the new score.

Check out the demo.


Conclusion

We have used External Interface to access the Local Storage API from HTML5. I hope you have found this tutorial useful and thanks for reading!

Advertisement