Monday, August 2, 2010

Formatting Externally Loaded Text In Flash ActionScript 3.0

This article is a continuation of the Loading External Text Files In Flash ActionScript 3.0 tutorial. In this lesson, we'll be using a TextFormat object to style our externally loaded text. So let's go back to the code and create the ff:
  • a TextFormat object (let's name it textStyle)
  • some text formatting properties (let's change the font and the size)
var myTextField:TextField = new TextField();
var textURL:URLRequest = new URLRequest("summer.txt");
var textLoader:URLLoader = new URLLoader();

// This next line creates the TextFormat object which will be used to
// change the text formatting
var textStyle:TextFormat = new TextFormat();

addChild(myTextField);

// Add in some formatting properties using the TextFormat object.
// Let's change the font to Verdana and the size to 14
textStyle.font = "Verdana";
textStyle.size = 14;

myTextField.border = true;
myTextField.multiline = true;
myTextField.wordWrap = true;
myTextField.width = 215;
myTextField.height = 225;
myTextField.x = 300;
myTextField. y = 50;

After creating the TextFormat object and setting some properties, we'll then need to apply the TextFormat object to our TextField. Otherwise, we won't see any formatting changes. To assign the TextFormat object to the TextField, we'll use the setTextFormat() method of the TextField class. The TextFormat object is passed to this method as a parameter. That's how it gets assigned to a specific TextField. Also, the setTextFormat() method must be used only after the text has been assigned to the TextField and not before. So in this example, we'll need to add this inside the displayText function, right after the line that says myTextField.text = e.target.data; .
function displayText(e:Event):void 
{
     myTextField.text = e.target.data;
     // This next line assigns the textStyle TextFormat object
     // to the TextField with the instance name myTextField
     myTextField.setTextFormat(textStyle); 
}
So now, if you test the movie, you should see the formatting changes applied to the text.

Here's the code in full:
import flash.text.TextField;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.text.TextFormat;

var myTextField:TextField = new TextField();
var textURL:URLRequest = new URLRequest("summer.txt");
var textLoader:URLLoader = new URLLoader();
var textStyle:TextFormat = new TextFormat();

addChild(myTextField);

textStyle.font = "Verdana";
textStyle.size = 14;

myTextField.border = true;
myTextField.multiline = true;
myTextField.wordWrap = true;
myTextField.width = 215;
myTextField.height = 225;
myTextField.x = 300;
myTextField. y = 50;

textLoader.addEventListener(Event.COMPLETE, displayText);

function displayText(e:Event):void 
{
     myTextField.text = e.target.data;
     myTextField.setTextFormat(textStyle);
}

textLoader.load(textURL);
You'll also notice that all the text does not fit inside the TextField anymore (since we made the font size larger). In the next part, we'll fix this by learning how to add a scrolling functionality for our TextField.

PREV: Loading External Text Files In Flash ActionScript 3.0
NEXT: Completing The Project: Adding Text Scrolling

Wednesday, July 28, 2010

Loading External Text Files In Flash ActionScript 3.0

Work Files:
Load_Text_Start.fla
summer.txt (right-click > save as )

In this article, we're going to learn how to load text from an external source into a Flash movie.

What is the benefit of loading text from an external source?
The nice thing about loading text externally is that when you need to update the text, then you simply need to edit the text file. You won't have to make changes to the .fla file anymore.

To load text from an external source, we will need the ff:
  • a plain text file that contains the text we would like to load
  • a URLRequest object to specify the path to the external text file
  • a URLLoader object which will load the external text file into the Flash movie
  • a TextField that will display the loaded text

2 exercise files accompany this tutorial:
  1. Load_Text_Start.fla - this is the Flash movie where the external text will be loaded into
  2. summer.txt - this is the plain text file that contains the text we will be loading into the Flash movie
The download links are found at the beginning of the article. Make sure that you save both files in the same folder. By the end of this tutorial, you should be able to load the external text into the Flash movie. And in succeeding articles, you will also learn how to format the text using a TextFormat object, and how to add text scrolling functionality.

So let's begin. Go ahead and open the Load_Text_Start.fla file. You will see that the document contains some artwork (a sun drawing) and 2 buttons (these buttons will be used to scroll the text up and down). We'll be creating a TextField which will be placed within the empty white area on the stage. This TextField will display the text loaded from the external source.

Let's now begin writing the code. Let's first create the TextField, add it to the display list and set some of it's properties. Select frame 1 of the Actions layer and go to the Actions Panel and type the ff:
// Create a TextField object
var myTextField:TextField = new TextField();

// Add the TextField object to the display list so that
// it will be visible on the stage
addChild(myTextField);

myTextField.border = true;
myTextField.multiline = true;
myTextField.wordWrap = true; 
myTextField.width = 215; 
myTextField.height = 225; 
myTextField.x = 300; 
myTextField. y = 50;

If you test your movie now, you should see the TextField just above the scroll buttons and to the right of the sun artwork.

Now that we have the TextField, we'll need a URLRequest object and a URLLoader object in order to load the external text file. The URLRequest allows us to specify the path to the external file that we would like to load. In this example, we want to load the summer.txt file, which we saved in the same folder as the Flash document. So since they are in the same directory, all we have to do is specify the filename summer.txt when we create the URLRequest object. The URLLoader, on the other hand, has the capability to load external text files into Flash movies. It is the URLRequest object that simply tells the URLLoader which file it's supposed to load.

So to recap, the URLRequest specifies which file is to be loaded, while the URLLoader is the one that loads the specified file. Now, let's go ahead and create the URLRequest and URLLoader objects:
var myTextField:TextField = new TextField();

// This next line creates the URLRequest object named textURL.
// The file name of the external text file to be loaded is
// passed as a parameter to the URLRequest constructor.
var textURL:URLRequest = new URLRequest("summer.txt");

// This next line creates a URLLoader object named textLoader
var textLoader:URLLoader = new URLLoader();

addChild(myTextField);

myTextField.border = true;
myTextField.multiline = true;
myTextField.wordWrap = true;
myTextField.width = 215;
myTextField.height = 225;
myTextField.x = 300;
myTextField. y = 50;

After creating the URLRequest and URLLoader objects, we can now tell Flash to load the external text file. The load() method of the URLLoader class is what instructs the URLLoader to load an external text file. The URLRequest object is passed as a parameter to the load() method so that the URLLoader will know which file it is supposed to load (ex. textLoader.load(textURL); ). But in addition to writing the load statement, we'll also need an event handler. Why is that? This is because we'll only be able to display the text in the TextField once the external text file has finished being loaded (and not while the loading process is still happening). Once the URLLoader begins to load the text file, we'll have to wait for the text file to be loaded completely, and only then can we display the text in the TextField. The event that will tell us when the file has been loaded completely is Event.COMPLETE (this event will be dispatched if and when the external text file has been successfully loaded). This event will be dispatched by the URLLoader object, so the event listener will be added to our URLLoader which we named textLoader. So let's go back to the Actions Panel and create the event handler and the load statement.
myTextField.border = true;
myTextField.multiline = true;
myTextField.wordWrap = true;
myTextField.width = 215;
myTextField.height = 225;
myTextField.x = 300;
myTextField. y = 50;

// This next lines adds an event listener that waits
// for the textLoader to completely load
// the external text file (Event.COMPLETE). Once loaded,
// the function named displayText will be called.
textLoader.addEventListener(Event.COMPLETE, displayText);

function displayText(e:Event):void 
{
     // This function will contain the code that will display the text in the 
     // TextField once the external text file has been loaded. But let's add
     // that code later. For now, let's just put in a trace statement.
     // This trace statement will just indicate that the file has loaded.
     trace("File loaded successfully.");
}

// This next line tells the TextLoader to load the
// external text file specified by the URLRequest object
// named textURL (which specifies the summer.txt file)
textLoader.load(textURL);

Now go ahead and test the movie. You should see the output window display the phrase File loaded successfully. So this means that the Event.COMPLETE event has been triggered and that the text file has been loaded successfully. If it doesn't, you might want to check that you typed in the correct file name - "summer.txt" - and that the text file is saved in the same directory as your Flash movie.

So now that the external text file has been loaded, where is the text? I don't see it.
What we've done so far is that we've simply just loaded the external text file. The text data is already in the Flash movie, we just haven't displayed it yet. So the next thing we need to do is to get the text data and then display it in the TextField.

Ok. So where exactly do I find the text data?
Once loaded, the text contained inside the external text file can be found in the URLLoader object that was used to load the external text file. That text can be accessed by using the data property of the URLLoader class (ex. textLoader.data).

And once I get the text data, how do I assign it to the TextField?
You'll use the same way you assign text to any TextField - by using the text property of the TextField class (ex. myTextField.text = textLoader.data; ). And REMEMBER, you'll have to do this only after the text file has been loaded completely. So you must place the text assignment statement inside the Event.COMPLETE listener function (which in this example is the displayText function).

So let's go back to the event listener function named displayText and let's remove the trace statement and replace it with the text assignment statement. But instead of typing textLoader.data inside the event listener function, we'll type in e.target.data . Since the even listener was added to the textLoader URLLoader object, then e.target will refer to textLoader as well. One advantage of using e.target is that we'll be able to use the same event listener function with other URLLoader objects as well (for example, we might want to have multiple URLLoader objects that load different external text files).
function displayText(e:Event):void 
{
     // This next line will assign the text from the external text file to the
     // TextField instance named myTextField
     myTextField.text = e.target.data;
}

Now if you test the movie, you should be able to see the text displayed inside the TextField.

Here's the code in full:
import flash.text.TextField;
import flash.net.URLRequest;
import flash.net.URLLoader;

var myTextField:TextField = new TextField();
var textURL:URLRequest = new URLRequest("summer.txt");
var textLoader:URLLoader = new URLLoader();

addChild(myTextField);

myTextField.border = true;
myTextField.multiline = true;
myTextField.wordWrap = true;
myTextField.width = 215;
myTextField.height = 225;
myTextField.x = 300;
myTextField. y = 50;

textLoader.addEventListener(Event.COMPLETE, displayText);

function displayText(e:Event):void 
{
     myTextField.text = e.target.data;
}

textLoader.load(textURL);

In the next part, we'll style the text using a TextFormat object.

NEXT: Formatting Externally Loaded Text In Flash ActionScript 3.0

Wednesday, July 21, 2010

Preloading in ActionScript 3.0 Part 2

Exercise Files:
Preloader02_Start.fla

bird.jpg
candles.jpg

We've learned about the basics of preloading in Part 1 of Preloading in ActionScript. In this lesson, we'll apply the same concepts to make a picture gallery that has the ability to preload the images. Links to the exercise files are provided at the beginning of this article. Make sure to save all these files in one folder.

Descriptions of Exercise Files

  1. bird.jpg and candles.jpg
    These 2 files will be loaded externally into the Flash movie we will create.
  2. Preloader02_Start.fla
    This Flash document has the following elements:
    • 2 Buttons - The instance names of the buttons are pic1_btn and pic2_btn. Clicking on these buttons will load the image files.
    • 1 TextField - The instance name of the TextField is percent_txt. This will display the loading progress of the image that is being loaded.

Go ahead and open the Preloader02_Start.fla file. Select frame 1 of the Actions layer and then go to the Actions Panel and place the code below (comments have been included to explain the code):
// Create the loader object that will be used to load the
// external image files. I've named it picLoader. We'll only
// need one loader since we don't plan on displaying the images
// at the same time. We only want to load and display them one
// at a time.
var picLoader:Loader = new Loader();

// Create the URLRequest objects that specify the filenames
// of the external image files. We need to create 1 URLRequest
// per image file. We have 2 images so we need to create two
// URLRequest objects. I've named the first one picURL1, which
// requests for bird.jpg. I've named the second one picURL2, which
// requests for candles.jpg.
var picURL1:URLRequest = new URLRequest("bird.jpg");
var picURL2:URLRequest = new URLRequest("candles.jpg");

// Add the event listeners for each of the buttons. We will
// use a CLICK event to tell Flash to respond. When any of
// the buttons are clicked, Flash will begin to load the
// corresponding image.
pic1_btn.addEventListener(MouseEvent.CLICK, clickOne);
pic2_btn.addEventListener(MouseEvent.CLICK, clickTwo);

// These are the event listener functions for the CLICK
// event handlers. I've created two different functions
// for each of the buttons since each button will be
// loading a different image. (but do know that there are
// more effecient ways to go about this).
// This clickOne event listener function is for when the
// pic1_btn button is clicked
function clickOne(e:MouseEvent):void
{
     // Add the event listeners for ProgressEvent.PROGRESS 
     // and Event.COMPLETE.
     // This is for the preloading of the images.
     picLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
     picLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);

     // This load statement below is the line that tells Flash to 
     // start loading the image.
     picLoader.load(picURL1);
}

// This next function does the same thing as the function above,
// except that it will load a different image as specified in the 
// load statement.
// This one is for the second button and will load 
// picURL2 (the candles.jpg image), while the other one will load 
// picURL1 (the bird.jpg image).
function clickTwo(e:MouseEvent):void
{
     picLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
     picLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
     picLoader.load(picURL2);
}

// This is the event listener function for ProgressEvent.PROGRESS.
// It contains the preloader formula.
function onProgress(e:ProgressEvent):void
{
     // The line below calculates how much of the file has already 
     // been loaded.
     var nPercent:Number = Math.round(e.target.bytesLoaded / e.target.bytesTotal * 100);

     // This next line outputs the results from the preloading 
     // calculations.
     // The value will be displayed in the percent_txt TextField 
     // on the stage.
     percent_txt.text = nPercent.toString() + " %";
}

// This is the event listener function for Event.COMPLETE 
// (dispatched when the image has successfully loaded completely).
function onComplete(e:Event):void
{
     // Remove the ProgressEvent.PROGRESS and Event.COMPLETE 
     // listeners once the image has been loaded.
     picLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgress);
     picLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);

     // Add the loader to the display list so that the image that 
     // was loaded will be visible on the stage.
     addChild(picLoader);

     // Adjust the x and y position of the loader so that it fits 
     // within the border drawn on the stage. If you don't put 
     // these lines, then the loader position will default to 
     // x = 0 and y = 0 (making it appear on the upper left corner 
     // of the stage.
     picLoader.x = 75;
     picLoader.y = 30;
}

Sunday, July 18, 2010

AS3 Timer - ActionScript 3 Tutorial | Introduction to the Flash ActionScript 3.0 Timer Class

The Flash AS3 Timer class lets you create Timer objects, one common usage of which would be to create counters for your Flash application - like an AS3 countdown timer, a time limit counter for a game or some sort of timer delay. In this tutorial, we'll learn the basics of working with the Timer ActionScript 3 class.

NOTE: For those of you coming from AS2 and have been using the setInterval() function - there is also an AS3 setInterval() function, but the AS3 Timer class is a good alternative to using setInterval().

A Timer object has the ability to count at a specific interval, which can be set using what is called the delay. The delay is specified in milliseconds. For example, if there is a delay of 1000 milliseconds, then the Timer object will count at 1 second intervals. If there is a delay of 5000 milliseconds, then the Timer counts every 5 seconds. You can specify a delay as short as 20 milliseconds, but anything lower than that is not recommended and may cause problems.

So now let's go ahead and create a new AS3 Timer object. The Timer ActionScript 3 constructor accepts 2 parameters. The first parameter is for the delay. The second parameter is for the repeatCount. The repeatCount specifies the number of repetitions the Timer will make. If you don't specify a repeatCount or if you specify zero, the timer repeats indefinitely. If you specify a positive nonzero value, then the timer runs at that specified number of times and then stops. So for example, if you specify a repeatCount of 5, then the Timer will count 5 times and then stop. The delay parameter is required, while the repeatCount is optional.
var myTimer:Timer = new Timer(1000);

This creates a new Timer object named myTimer. A delay of one second has been specified.

NOTE: The delay is not always 100% accurate. It will usually be off by a few milliseconds, but in many cases, it's barely noticeable.

The Timer will not start automatically. Use the start() method of the Timer class in order to tell the Timer object to start.
var myTimer:Timer = new Timer(1000);
myTimer.start();

If you test your movie now, the Flash movie will launch, but you won't see anything happen. In order to tell Flash to respond and do something, then we'll need to create AS3 Timer event handlers so that our Flash movie will know what to do when certain Timer associated events get dispatched.

Let's first take a look at the TimerEvent.TIMER event. This event gets dispatched every time the Timer object makes a count. So for example, if you have a Timer object that has a 1 second delay, then TimerEvent.TIMER will get dispatched every 1 second. This event is useful if you'd like your Flash movie to do something repeatedly at a constant interval. So let's go ahead and create a TimerEvent.TIMER event handler that will tell Flash to display the word hello in the output window every time the Timer makes a count.
var myTimer:Timer = new Timer(1000);
myTimer.start();

myTimer.addEventListener(TimerEvent.TIMER, sayHello);

function sayHello(e:TimerEvent):void {
     trace("hello");
}

So now, if you test the movie, you will see the word hello come out in the output window every 1 second.

If you wish to keep track of how many times the Timer has been counting, then you can use the currentCount property of the Timer class. Each time the Timer makes a count, the currentCount property increases by 1. Let's add a trace statement that's going to output the Timer object's currentCount value every time the Timer makes a count.
var myTimer:Timer = new Timer(1000);
myTimer.start();

myTimer.addEventListener(TimerEvent.TIMER,  sayHello);

function sayHello(e:TimerEvent):void 
{
     trace("hello");
     trace("Current Count: " + myTimer.currentCount);
}

NOTE: The currentCount property begins at 0, but when you test the movie, you will see that the first value displayed is 1. This is because the Timer will only begin dispatching TimerEvent.TIMER after it makes that first count from 0 to 1. Also note that if you stop the Timer and then start it again, the currentCount will continue counting from that last value that it stopped at. To reset the currentCount property of a Timer object back to 0, then you can use the reset() method of the Timer class ( ex. myTimer.reset(); ). If the Timer is running, then the reset() method will also stop the Timer.

The other event that gets dispatched by the AS3 Timer object is the TimerEvent.TIMER_COMPLETE event. This gets dispatched when the Timer has completed the number of counts as set by the repeatCount parameter.

So let's go ahead and add in a repeatCount of 10, and then let's create an event handler for the TimerEvent.TIMER_COMPLETE event. Let's tell the Flash movie to output the word bye once it completes the specified number of counts.
var myTimer:Timer = new Timer(1000, 10);
myTimer.start();

myTimer.addEventListener(TimerEvent.TIMER, sayHello);
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, sayBye);

function sayHello(e:TimerEvent):void 
{
     trace("hello");
     trace("Current Count: " + myTimer.currentCount);
}

function sayBye(e:TimerEvent):void 
{     
     trace("bye");
}

So in the example above, the Timer will count 10 times. Each time it makes a count, the word hello will come out in the output window, and the currentCount value will increase by 1. Once it reaches 10, then the TimerEvent.TIMER_COMPLETE event gets dispatched, and you will see the word bye come out in the output window.

And that concludes this AS3 Timer - ActionScript 3 tutorial.

Wednesday, January 20, 2010

Flash AS3 Volume Control Tutorial

Exercise Files:
Adjusting_Volume_Start.fla
CheerfulSong.mp3

NOTE: Be sure to save both files in the same folder.

To adjust sound volume in Flash, you will need a SoundTransform object. The SoundTransform class has a volume property, which you can assign a value from 0 - 1. Where 0 is mute, and 1 is full volume.

For example:
var volumeAdjust:SoundTransform = new SoundTransform();
volumeAdjust.volume = .5;
The first line creates a SoundTransform object named volumeAdjust. The next line sets the volume property to .5.

But this doesn't adjust the volume of the sound just yet. Yes, we've set a new volume level, but we still haven't applied it to any sound. So after creating the SoundTransform object and setting the volume level, we must then apply the SoundTransform object to a specific SoundChannel. You can do this using the soundTransform property of the SoundChannel class.

NOTE: Be aware of the distinction between a SoundTransform object (which would be an instance of the SoundTransform class) and the soundTransform property (which is a property of the SoundChannel class). A SoundTransform object is what holds the value for the volume level adjustment, where as the soundTransform property of the SoundChannel class is used in order to apply that volume level adjustment to the sound. Also notice that the soundTransform property starts with a lowercase s, while the SoundTransform class starts with an uppercase S.

Example:
// Assume that channel1 is a SoundChannel object and that there is
// already a sound assigned to that channel
channel1.soundTransform = volumeAdjust;
This statement assigns the SoundTransform object named volumeAdjust, to the soundTransform property of the SoundChannel object named channel1. So this means that whatever sound is being played on that SoundChannel will have the volume adjustment applied to it.

NOTE: The volume property can actually accept values that are greater than 1, as well as negative values. But generally, you should only allow values between 0 - 1 (nothing greater nothing less) because values outside that range can end up distorting the sound. Negative values will actually increase the volume as well. So if the volume property has a value that goes below 0, the sound volume comes back up. You can use an if statement with an else clause in order to set constraints (which we will do later on).

So let's begin.

Open the exercise file and select the first frame of the Actions layer. In the Actions Panel, you'll see that there's already some code:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();

mySound.load(songURL);

play_btn.addEventListener(MouseEvent.CLICK, playSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);

function playSound(e:MouseEvent):void 
{
     channel1 = mySound.play();
}

function stopSound(e:MouseEvent):void 
{
     channel1.stop();
}
This code just loads the sound and creates the playing and stopping functionality. We will just be adding the volume controls.

On the stage, you will see two small buttons: one pointing up (volUp_btn) and one pointing down (volDown_btn). These buttons will be made clickable in order to adjust the volume.

But first, let's go ahead an create the SoundTransform object. I will name it volumeAdjust:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();
var volumeAdjust:SoundTransform = new SoundTransform();

mySound.load(songURL);

Next, let's go ahead and create the event handlers for the volume buttons. I will name the listener functions volUp (for increasing the volume) and volDown (for decreasing the volume):
play_btn.addEventListener(MouseEvent.CLICK, playSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);
volUp_btn.addEventListener(MouseEvent.CLICK, volUp);
volDown_btn.addEventListener(MouseEvent.CLICK, volDown);

function playSound(e:MouseEvent):void
{
     channel1 = mySound.play();
}

function stopSound(e:MouseEvent):void 
{
     channel1.stop();
}

function volUp(e:MouseEvent):void 
{
     //code to increase the volume goes here
}

function volDown(e:MouseEvent):void 
{
     //code to decrease the volume goes here
}

Next, let's set the initial volume.

Set the volume property of the SoundTransform object to the desired level. I will give it a value of .5:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();
var volumeAdjust:SoundTransform = new SoundTransform();

volumeAdjust.volume = .5;
Then go to the playSound function (that's the listener function that's called whenever the play button is clicked) and add the following line (highlighted in bold):
function playSound(e:MouseEvent):void 
{
     channel1 = mySound.play();
     channel1.soundTransform = volumeAdjust;
}
Code explained:
volumeAdjust.volume = .5;
This line sets the volume property of the SoundTransform object to .5 (which is at half the full volume level).

channel1.soundTransform = volumeAdjust;
Then to apply the change in volume, the volumeAdjust SoundTransform object is assigned to the soundTransform property of channel1. It's important to note that this line must be added after the play sound statement is assigned to the SoundChannel object. Otherwise, the volume change will not be applied.

So now, we've set the initial volume to .5. Test the movie and try applying different volume levels in order to hear the difference. Try putting in a value greater than 1 (around 15-20, for example) and you will notice some sound distortion (be sure to keep your ears a comfortable distance away from the sound source when you do this). Then make sure you bring it back down to .5 when you continue the tutorial.

After setting the initial volume, let's now start working on the buttons for adjusting the volume.

To increase the volume, we can simply increment the value of the SoundTransform object's volume property whenever the volume up button is clicked. Go to the volUp listener function and add the following lines highlighted in bold:
function volUp(e:MouseEvent):void 
{
     volumeAdjust.volume += .1;
     channel1.soundTransform = volumeAdjust;
}

Code explained:
volumeAdjust.volume += .1;
This line increments the current volume property value by .1. So every time the volume up button is clicked, the volume property's value increases by .1.

channel1.soundTransform = volumeAdjust;
Every time changes are made to the volume property of the SoundTransform object, it must be reapplied to the SoundChannel's soundTransform property in order for the changes to take effect. So you have to make sure that you add this line as well.

But wait! Early on, I mentioned that continuously increasing the volume way above a value of 1 will end up distorting the sound. So we'll need to limit the volume adjustment to a range of just 0 to 1. In order to do that, we can use if statements.

Go back to the volUp function and add the following (highlighted in bold):
function volUp(e:MouseEvent):void 
{
     volumeAdjust.volume += .1;
     if(volumeAdjust.volume > 1)
     {
          volumeAdjust.volume = 1;
     } 
     channel1.soundTransform = volumeAdjust;
}
Code explained:
So whenever the volume up button is clicked, the volume property is incremented first. Then before the volume adjustment is applied using the soundTransform property, the if statement checks whether the new volume value has gone over 1. If it has, then the volume property value is immediately brought back down to 1, before the volume adjustment is applied. This effectively limits the maximum volume to 1 no matter how many times the volume button is pressed.

And lastly, for decreasing the volume, we use the same concept. Except for this one, we would like to DECREMENT the value of the volume property instead. And for the if statement, we would like to check whether the volume property's value is LESS THAN 0. Whenever it goes below 0, then we want to immediately pull it back up again to 0. So that way, we effectively limit the minimum volume to 0. So go to the volDown function and add the following lines highlighted in bold:
function volDown(e:MouseEvent):void 
{
     volumeAdjust.volume -= .1;
     if(volumeAdjust.volume < 0)
     {
          volumeAdjust.volume = 0;
     } 
     channel1.soundTransform = volumeAdjust;
}
So there you have it. You've just created simple volume controls in ActionScript 3.0.

Here's the code in full:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();
var volumeAdjust:SoundTransform = new SoundTransform();

volumeAdjust.volume = .5;

mySound.load(songURL);

play_btn.addEventListener(MouseEvent.CLICK, playSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);
volUp_btn.addEventListener(MouseEvent.CLICK, volUp);
volDown_btn.addEventListener(MouseEvent.CLICK, volDown);

function playSound(e:MouseEvent):void 
{
  channel1 = mySound.play();
  channel1.soundTransform = volumeAdjust;
}

function stopSound(e:MouseEvent):void 
{
  channel1.stop();
}

function volUp(e:MouseEvent):void 
{
  volumeAdjust.volume += .1;
  if(volumeAdjust.volume > 1)
  {
    volumeAdjust.volume = 1;
  } 
  channel1.soundTransform = volumeAdjust;
}

function volDown(e:MouseEvent):void 
{
  volumeAdjust.volume -= .1;
  if(volumeAdjust.volume < 0) 
  {
    volumeAdjust.volume = 0;
  } 
  channel1.soundTransform = volumeAdjust;
}

Monday, January 18, 2010

Pausing and Resuming Sound in ActionScript 3.0

Exercise Files:
Pausing_Sound_Start.fla
CheerfulSong.mp3

NOTE: Be sure to save both files in the same folder.

In ActionScript 3.0, you can start playing a sound file using the play() method of the Sound class. And in order to stop playing a sound file, you use the stop() method of the SoundChannel class. Pausing the sound however, is not as straightforward. Pausing and resuming sound in ActionScript 3.0 involves a few extra elements.

When pausing sound in ActionScript 3.0, it's important to note that you're not actually pausing the sound. You will still need to stop the sound using the stop() method of the SoundChannel class. But before you stop the sound, you'll need to find a way to tell Flash to remember at which point along the sound file's playback it's currently on. Say for example you stop the sound file at the 10 second mark of the song, you will then need to store that information in a variable and then tell flash to resume playing at that same position when the song is played again. In other words, you're telling Flash to "remember" where the song was before it was stopped.

So how do you know the current position of the sound that is being played?
You'll need to use the position property of the SoundChannel class. The position property refers to the current position of the sound as it is being played. This gives you a value in milliseconds. You can store this value in a Number variable so that Flash can "remember" where the sound was at before it was stopped.

So now that Flash "remembers" the position, how do you tell it to resume playing at that same point?
The play() method of the Sound class has an offset parameter. It's an optional parameter that allows you to start playing a sound at a point other than the beginning. For example:

mySound.play(10000);
//10000 stands for 10000 milliseconds

This tells Flash to start playing the sound at the 10000 millisecond position. Take note that this is NOT a delay. The sound file is going to play immediately. It's simply going to skip the first 9 seconds of the song and start playing at the 10 second mark (the offset will read the value in milliseconds though, so you'll have to specify 1000 for 1 second, 2000 for 2 seconds and so on...).

So now you can store the sound file's current position in a Number variable, then use the offset parameter so that it can resume playing at that same position. For example:

//Let's say that this is the variable that will be used to store the position of the sound
var resumeTime:Number = 0;

//You can then associate the variable with the offset parameter like so:
mySound.play(resumeTime);
Let's begin.

Open the Flash exercise file and take a moment to observe the elements on the stage. You'll see a play button (play_btn) and a stop button (stop_btn). There's also a pause button (pause_btn). The pause button however is hidden underneath the play button. Move the play button to a different position in order to see the pause button (but be sure to bring it back to the original position where it's covering the pause button). Later on, we'll toggle the visibility of the play and the pause button so that when one of them is clicked, it becomes invisible so that the other one is revealed.

Create the following variables:
//This will be used to load the external mp3 file as well as to start playing the sound
var mySound:Sound = new Sound();

//Use a URLRequest to specify the path to the sound file to be loaded
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");

//This creates the SoundChannel object for the sound file to be played
var channel1:SoundChannel = new SoundChannel();

//This is the variable that will be used for the pause functionality.
//It will be used to store the sound file's position just right before it's stopped.
//Initialize it to 0 so that the sound file will play at the very beginning the first time the song is played.
var resumeTime:Number = 0;

Then use the load method of the Sound class to load the external sound file:
mySound.load(songURL);


Then create the event Handlers for the play, pause and stop buttons:
play_btn.addEventListener(MouseEvent.CLICK, playSound);
pause_btn.addEventListener(MouseEvent.CLICK, pauseSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);

function playSound(e:MouseEvent):void
{
//Code for starting and resuming sound playback goes here
}

function pauseSound(e:MouseEvent):void 
{
//Code for the pausing functionality goes here
}

function stopSound(e:MouseEvent):void 
{
//Code for stopping the sound goes here
}

Let's go ahead and complete the playSound function first (which is responsible for starting and resuming sound playback):
function playSound(e:MouseEvent):void
{
  channel1 = mySound.play(resumeTime);
  play_btn.visible = false;
  pause_btn.visible = true;
}

Code explained:
channel1 = mySound.play(resumeTime);
This plays the sound file. It will be assigned to the channel1 SoundChannel object. You have to assign it to the SoundChannel object because the SoundChannel will be used to stop the sound and to get it's current position. The resumeTime variable is then specified as the offset parameter of the play method so that the sound file will begin playing at whatever value is stored in resumeTime.

play_btn.visible = false;
pause_btn.visible = true;
These lines toggle the visibility of the play and pause buttons. Upon clicking the play button, it will become invisible in order to reveal the pause button underneath.

And now for the pause functionality. This function will be called whenever the pause button is clicked:
function pauseSound(e:MouseEvent):void 
{
  resumeTime = channel1.position;
  channel1.stop();
  pause_btn.visible = false;
  play_btn.visible = true;
}

Code explained:
resumeTime = channel1.position;
channel1.stop();
Upon clicking the pause button, the sound file's current position is retrieved and then stored in the resumeTime variable. The sound is then immediately stopped.
pause_btn.visible = false;
play_btn.visible = true;
Just like in the previous function, this toggles the visibility of the play and pause buttons. But this time, when the pause button is clicked, it becomes invisible while the play button becomes visible again.

And now for the function assigned to the stop button:
function stopSound(e:MouseEvent):void 
{
  //This stops the sound
  channel1.stop();

  //Be sure to reset the resumeTime variable back to 0, otherwise, 
  //the playback will resume at the same point when it was previously paused
  resumeTime = 0;

  //Make sure that the play button is visible and the pause button 
  //is hidden whenever the stop button is clicked
  play_btn.visible = true;
  pause_btn.visible = false;
}

There's one more thing we need to add. If you test the Flash movie now, you will notice that when the song reaches the end, the play button does not come back, so you're just stuck with the pause button. We want the play button to come back once the song finishes playing. So let's add a SOUND_COMPLETE event handler for that. Whenever the song finishes playing, we need to make sure that the the play button will be visible again. In addition, we'll have to reset the resumeTime variable back to 0 to ensure that the sound will play from the very beginning once the user clicks on the play button again.

So first, go back to the playSound function and create the addEventListener statement for whenever the sound finishes playing. The event is Event.SOUND_COMPLETE and we'll name the function to be called when the event is triggered as onSongEnd:
function playSound(e:MouseEvent):void
{
  channel1 = mySound.play(resumeTime);

  channel1.addEventListener(Event.SOUND_COMPLETE, onSongEnd);
  // Remember that this should only be added after the play sound statement
  // is assigned to the SoundChannel

  play_btn.visible = false;
  pause_btn.visible = true;
}

Next, let's create the listener function for our SOUND_COMPLETE event handler. You can place this right after the stopSound function.
function onSongEnd(e:Event):void 
{
  //This sets resumeTime back to 0 so that the sound plays at the beginning
  //the next time it is played
  resumeTime = 0;

  //This makes sure that the play button is visible and the pause button is not
  play_btn.visible = true;
  pause_btn.visible = false;
}

So there you have it. You've just learned how to successfully pause and resume sound playback.

Here's the code in full:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();
var resumeTime:Number = 0;

mySound.load(songURL);

play_btn.addEventListener(MouseEvent.CLICK, playSound);
pause_btn.addEventListener(MouseEvent.CLICK, pauseSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);

function playSound(e:MouseEvent):void
{
  channel1 = mySound.play(resumeTime);
  channel1.addEventListener(Event.SOUND_COMPLETE, onSongEnd);
  play_btn.visible = false;
  pause_btn.visible = true;
}

function pauseSound(e:MouseEvent):void 
{
  resumeTime = channel1.position;
  channel1.stop();
  pause_btn.visible = false;
  play_btn.visible = true;
}

function stopSound(e:MouseEvent):void 
{
  channel1.stop();
  resumeTime = 0;
  play_btn.visible = true;
  pause_btn.visible = false;
}

function onSongEnd(e:Event):void 
{
  resumeTime = 0;
  play_btn.visible = true;
  pause_btn.visible = false;
}

Thursday, December 3, 2009

Preloading in ActionScript 3.0 Part 1

Exercise Files:
Preloader01_Start.fla
allin.swf

In this tutorial, we are going to learn how to create a preloader in Flash using ActionScript 3.

What is a preloader and what is it for?
Flash movies tend to have larger than average file sizes compared to HTML websites. So when you create a Flash website, chances are, it will take a while to load every time a user visits it. That's why it's important to give the user an indication regarding how much longer he or she has to wait. This can be done by adding a preloader to your Flash website. A preloader is simply a kind of visual feedback that shows the user how much of the Flash website has already been loaded. A simple preloader can show nothing more that just a basic progress bar and some text that displays the loading percentage, while other Flash websites will have fancier preloaders that contain more complex animation and design. Regardless of the complexity of the preloader that you choose to make, it's always a good idea to have one for your Flash website. Without a preloader, the visitor might just get a blank browser window at first and think that the website is broken. And instead of waiting for the site to load, the user will more likely end up leaving your website.

How can I create a preloader in Flash?
There are a couple of methods that you can use to create a preloader in Flash. The method that we will take a look at in this tutorial involves the use of 2 Flash movies. One would be your actual Flash movie or website, while the other Flash movie is the one that will preload the Flash website. So here, we have a dedicated Flash movie that will do the actual preloading.


What's going to happen is that the Flash website gets loaded into the preloader Flash movie.


As the Flash website gets loaded into the preloader Flash movie, the preloader Flash movie will calculate and display the loading progress. To do this, the preloader Flash movie needs to contain the ff:
  • the ActionScript code that does the preloading
  • the visual elements of the preloader (such as the progress bar and the percentage text field)


 This tutorial comes with 2 exercise files:
  1. Preloader01_Start.fla
    This will generate our preloader Flash movie. This is where we will put the ActionScript 3 code for preloading a Flash website or file.
  2. allin.swf
    This is the Flash movie that we will be preloading. It just contains a picture of some poker chips and some animated text that says "all in".

Make sure that you save both files in the same folder. Otherwise, the preloader Flash movie might not find the Flash movie that we want to preload.

Let's first take a look at the contents of our preloader Flash movie. So go ahead and open the Preloader01_Start.fla file. On the stage you will see a movie clip instance named progressBar_mc and a dynamic text field named percent_txt.


They will both be used to indicate the loading progress. The progress bar gets fuller as the loading progresses, and the text field shows the percentage value of how much has already been loaded.

If you look at the main timeline, you'll see that it has only one frame. But if you go inside the progress bar movie clip, you'll see that it contains some animation inside it. You can double-click on the progress bar movie clip to go inside its timeline.  

NOTE: If you have trouble selecting the progress bar, make sure that you click on the border.

Once you're inside the progress bar movie clip's timeline, you'll see that it contains a layer named bar that has a shape tween.


This shape tween shows the progress bar going from empty to full. You can test the movie to see how it looks like. But when you test it, you'll just see the progress bar animate and loop endlessly. You won't see the text field update itself, and you won't see anything load yet. That's because we haven't added any code.

This progress bar animation will be used to represent the loading progress. You'll notice that the animation inside the progress bar movie clip's timeline is made up of 100 frames.


This is not an arbitrary number. The animation really has to have 100 frames because we want it to represent 100%. Each frame of the animation, represents one percent of the file that we are going to preload. The great thing about this is that you can just replace the animation with something else if you want a different progress bar. Just make sure that it has 100 frames. It doesn't even have to be a progress bar. You can be more creative with your preloader animation if you want. But don't go too overboard with your preloader animation. If you do, then your preloader Flash movie might end up having such a large file size that it will end up needing its own preloader.

REMEMBER: The animation is INSIDE the progress bar movie clip's timeline, NOT on the main timeline.

So let's begin adding our ActionScript 3 preloader code. If you're still inside the timeline of the progress bar movie clip, make sure that you go back to the main timeline by clicking on the Scene 1 link.

Once you're back on the main timeline, select frame 1 of the Actions layer and then open up the Actions panel.

STEP 1

First, let's stop the progress bar animation. We don't want the progress bar to start moving right away. We only want it to start moving once the loading process has started. So make it stop using the stop() method.
progressBar_mc.stop();

STEP 2

Then create a Loader and a URLRequest object:
progressBar_mc.stop();

var myLoader:Loader = new Loader();
var myURL:URLRequest = new URLRequest("allin.swf");

What are these objects for?
Loader objects are used to load external SWF files into a Flash movie. So this Loader object is going to be responsible for loading the Flash movie that we want to preload. Without this object, then we would not be able to load our main Flash movie into our preloader Flash movie. In our example, the external file that we want to load would be allin.swf.

NOTE: Aside from being able to load SWF files, Loader objects also have the ability to load JPG, PNG, and GIF files.

The URLRequest object is used to specify the path to the external file that you would like to load. This is what will tell the Loader what it's supposed to load. In this example, we want to load the allin.swf file, so that's why we typed the file name inside the parentheses of the URLRequest() constructor.

NOTE: You must pass the file name or path to the URLRequest() constructor as a string. So it should be in quotation marks.

So to recap, the Loader object loads the file, while the URLRequest is used to specify the path to the file that needs to be loaded.

STEP 3

At this point, let's now load the external SWF file into our preloader flash movie. But before we continue, I must warn you: after we load the external SWF file, we won't see it yet. But that's ok. We'll fix that later on.

To load the external file, we use the load() method of the Loader class. The load() method needs an argument. It needs to know which file you want to load. We've already specified that when we created the URLRequest object. So we simply pass the URLRequest object as an argument to the load() method.

So let's go ahead and use myLoader (our Loader object) to load allin.swf (the external SWF file that we want to preload as specified in the myURL URLRequest object) using the load() method. Go back to the code and add the load() statement highlighted in bold:
progressBar_mc.stop();

var myLoader:Loader = new Loader();
var myURL:URLRequest = new URLRequest("allin.swf");

myLoader.load(myURL);

So this new line that we've added tells the myLoader object to begin loading the file requested by the myURL object (which is allin.swf). Without this line, then the loading will not start.

But remember, as I've mentioned earlier, when we test the movie, we won't see the file come out on the stage just yet. That's because we've told Flash to load it, but we haven't told Flash to display it yet. Loading and displaying are two different things. But don't worry, we'll fix that later on.

STEP 4

Next, we'll need some event handlers. These event handlers that we're about to add are events that relate to the loading progress and loading completion of our external file. These events are:
1. ProgressEvent.PROGRESS
This event refers to the progress of the loading process. It is active all throughout the time that the external file is being loaded. The event is dispatched every time new data from the external file is being loaded into the Flash document by the Loader.
2. Event.COMPLETE
This event is dispatched when the external file has successfully completed the loading process.

I'll explain what these event handlers will do later on, but for now, add the following code highlighted in bold:
progressBar_mc.stop();

var myLoader:Loader = new Loader();
var myURL:URLRequest = new URLRequest("allin.swf");

myLoader.load(myURL); 

myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loading);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);

function loading(e:ProgressEvent):void
{
//This will contain the formula that will calculate the loading progress
//as well as the code that will control the progress bar animation
//and the text field output
}

function loaded(e:Event):void
{
//Here, we will specify what will happen once the file has loaded successfully
}

NOTE: These two event listeners that I just mentioned are NOT added directly to the Loader object. You add them to the contentLoaderInfo property of the Loader object instead. So instead of typing myLoader.addEventListener(...), you'll type in myLoader.contentLoaderInfo.addEventListener(...).

STEP 5

Right now, we just created 2 empty event listener functions. One for ProgressEvent.PROGRESS, and another one for EVENT.Complete.

Let's go ahead and complete the loading function first. This function is the one that we assigned to the ProgressEvent.PROGRESS event, so this means that this function will get called numerous times - it will be called each time new data from the external file gets loaded into our preloader Flash movie. So basically, this event keeps happening as the loading progress occurs (hence the name ProgressEvent.PROGRESS). Because of that, we can use it to write some code that will calculate and update the user regarding the loading progress.

Go to the loading function, and add the following lines highlighted in bold:
function loading(e:ProgressEvent):void
{
var nPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
percent_txt.text = nPercent.toString() + "%";
progressBar_mc.gotoAndStop(nPercent);
}

So now we just added 3 new lines inside the loading function. Let's try to understand what these lines are for.

1st line: var nPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
The first line calculates for the loading percentage. In order to calculate for the loading percentage, you will need to get the amount of bytes that have already been loaded, and divide it by the external file's total number of bytes. And then we multiply that value by 100 to convert the value into percent.

So how do I get the number of bytes that have been loaded and the total number of bytes?
This information automatically gets passed to the ProgressEvent.PROGRESS listener function (which in this case is our loading function). The number of bytes that have already been loaded can be retrieved using the bytesLoaded property, while the file's total number of bytes can be retrieved using the bytesTotal property. To access these properties, we use our event object - e:

e.bytesLoaded - the number of bytes that have been loaded
e.bytesTotal - the external file's total number of bytes (or its total file size)

Then divide those two values and multiply by 100 to get the percentage value.
e.bytesLoaded / e.bytesTotal * 100;

Then use Math.round() in order to round the value to a whole number.
Math.round(e.bytesLoaded / e.bytesTotal * 100);

Then we assign the equation to a variable (which I named nPercent):
var nPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);

And that is what the first line in the loading function means.

We will then use this nPercent variable for 2 things: (1) to display the percentage value in the text field and (2) to control the animation of the progress bar.

2nd line: percent_txt.text = nPercent.toString() + "%";
The second line in the loading function displays the value of nPercent in the dynamic text field on the stage. I've named the dynamic text field percent_txt. The text property of the TextField class lets you assign the text that you want to appear in the text field. So we assign the nPercent variable to it in order to display its value in the text field. However, nPercent is of the Number data type. Text fields can only display strings so we simply convert nPercent to the String data type using the toString() method. If you want the number to appear with a percent sign, then simply concatenate the value with the percent(%) character.

NOTE: The toString() method will not convert the numbers into letters. For example, 4 will not be converted to four. It will still be displayed as 4 but will be treated as a String instead of a Number. We need to do that so that the text field will accept it.

3rd line: progressBar_mc.gotoAndStop(nPercent);
The last line in the loading function controls the timeline of the progressBar_mc MovieClip. Recall that there is a 100 frame animation inside this MovieClip. On frame 1, the progress bar is empty. As the animation progresses, then the progress bar fills up until it is completely filled at frame 100. There's a reason why we want the animation to have 100 frames. We want to associate each frame number with the percentage of data that has been loaded. If 20% of the external file has been loaded, then we want the playhead to move to frame 20 of the progress bar animation. If 50% of the data has been loaded, then we want the playhead to move to frame 50, and so on... In order to do that, we can use the gotoAndStop() method of the MovieClip class and pass nPercent to it. So as nPercent increases, then the animation moves forward in sync with the percentage value.

NOTE: It is important that nPercent is rounded to a whole number because of this line. That's why we used Math.round() to round it. We cannot tell Flash to go to a frame no. 25.43, for example, since there is no frame no. 25.43. Frame numbers are always whole numbers.

And that completes our loading function. In the next step, we'll test the movie, but we'll simulate the download process when we do the testing. This means we'll make the movie behave as if we're actually viewing it online, so instead of finishing the loading process right away, we'll wait a while as if we were actually viewing it online. We want to simulate the download so that we can actually see the progress bar update. If we didn't simulate the download, then everything will just load right away.

STEP 6

How do we simulate the download?
First, you must test the movie. The keyboard shortcut for testing the movie is ctrl + enter (Windows) or cmd + return (Mac).

Once you test the movie, you should see the progress indicators go to 100% right away. This means that the external SWF file has already been loaded (but remember, you won't see it yet!). That was pretty fast! We just tested the movie, and all of sudden it loads right away. That's because our files are just in our hard drive. So let's change a few settings that will make Flash pretend as if we were testing this online instead.

So while the test movie window is still there, go to the View menu. If you're on a Mac, the View menu can be found in the menu bar at the top of your Flash workspace. If you're on Windows, the View menu can be found at the top of the actual test movie window.

So go to View, and then go to Download Settings, and then choose the desired download speed. Let's choose the 56K speed. This means that when we test the movie, Flash is going to behave as if we were viewing it online using a 56K connection. This is a pretty slow connection, so our small external SWF file should take about 7 to 8 seconds to load.

Now that we've chosen a speed, go to View again, and then choose Simulate Download. This will test the movie again, but will behave as if we we're viewing it with a 56K connection. This time, you should now see the progress bar update.

At this point, you still won't see the external SWF file appear on the stage. But it is being loaded. We'll be fixing the code soon so that we actually get to see the allin.swf file once the loading completes.

STEP 7

Let's now go to the loaded function and put some code inside it. The loaded function is the listener function that we assigned to  EVENT.Complete. This means that this function will get called, once myLoader finishes loading the external SWF file. So whatever it is that we want to happen once the loading is complete, we should place in this function.

One of the first things we want to do is to remove the progress bar and text field from the stage. Some people might want to leave these visible, but I prefer to remove them so the stage won't be so cluttered.

So go to the loaded function, and add the following lines:
function loaded(e:Event):void
{
removeChild(progressBar_mc);
removeChild(percent_txt);
}

Once the loading is complete, these 2 lines will remove the progressBar_mc and percent_txt display objects from the stage.

NOTE: Another option would be to use the visible property:
progressBar_mc.visible = false;
percent_txt.visible = false;

STEP 8

So now, test the movie again. Be sure to simulate the download. You should see the progress bar and text field disapper once it gets to 100%.

STEP 9

So now, let's go ahead and make sure that we actually see the externally loaded SWF file once the loading is complete. To do that, we need to add it to the display list. If we can remove things from the display list using removeChild(), then we can add things to the display list using addChild(). When you add something to the display list, it means that the display object can now be seen.

So go back to the loaded function and add the following line highlighted in bold:
function loaded(e:Event):void
{
removeChild(progressBar_mc);
removeChild(percent_txt);
addChild(myLoader);
}

So here, we are adding myLoader to the display list. We should now see the externally loaded SWF file show up on the stage once the loading is complete.

But why are we adding myLoader? Shouldn't we add allin.swf?
allin.swf is actually inside myLoader. When a Loader object loads an external file, the external file is actually loaded inside the Loader object itself. So the external file becomes a child of the Loader object that loaded it. So if you add the Loader to the display list, then its child gets added as well.

STEP 10

So now, go ahead and test the movie. Be sure to simulate the download as well. And you should now see the externally loaded SWF file appear on stage once the loading is complete.

STEP 11

Lastly, I want to remove a few more things once the loading is complete. I want to remove the event listeners that we created. So go back inside the loaded function and add removeEventListener() statements for the ProgressEvent.PROGRESS and Event.COMPLETE listeners.

function loaded(e:Event):void
{
removeChild(progressBar_mc);
removeChild(percent_txt);
addChild(myLoader);
myLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, loading);
myLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaded);
}

Why are we removing them?
In this case, it's because we no longer need them once the loading is complete. It's a good habit to remove listeners that you no longer need. It might help you save more computing resources in the long run, especially if you have a pretty heavy Flash movie. But if your Flash movie needs to preload something again, you might need to keep the event listeners available instead of removing them. Or you can also just add them again at some point in your code. Likewise, you should add the progressBar_mc and percent_txt display objects back to the stage if your Flash movie needs to preload another external SWF file. If you try to remove something that's already been removed using removeChild(), then you'll get an error message. So be sure to add those back if you need them again. But in this example, we're only loading one external SWF file, so there won't be a need for that.

NOTE: Each Loader object can only load an external file one at a time. If you want to load multiple external files all at once, then you should create multiple Loader objects.

And that completes our preloader. Here's the full code:
progressBar_mc.stop();

var myLoader:Loader = new Loader();
var myURL:URLRequest = new URLRequest("allin.swf");

myLoader.load(myURL); 

myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loading);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);

function loading(e:ProgressEvent):void
{
var nPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
percent_txt.text = nPercent.toString() + "%";
progressBar_mc.gotoAndStop(nPercent);
}

function loaded(e:Event):void
{
removeChild(progressBar_mc);
removeChild(percent_txt);
addChild(myLoader);
myLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, loading);
myLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaded);
}

Go to Part 2 (Preloading in ActionScript 3.0)

Sunday, November 1, 2009

Flash CS4 Drawing Tools

The following tools highlighted in the picture below can be used to draw things on the stage of your Flash CS4 document:

The tools highlighted in the image are (clockwise):
Pen tool, Line tool, Rectangle tool, Deco tool, Brush tool and Pencil tool

Some of the tool icons that you see have a tiny little triangle on the lower-right corner. Click and hold these icons and you will see a menu pop out. This menu contains other tools that you can use in place of the one that's currently visible on the toolbar. Simply click on the new tool that you want to use in order to switch to that tool.

Monday, May 4, 2009

Photoshop: Copying a Layer onto a New Document



You can use the Move tool to copy a layer onto a new document.

Choose the Move tool from the Tools panel. Select the layer you want to copy then click and drag it to the new document where you want to copy it to.

To copy multiple layers, make multiple layer selections in the layers palette.
  • To make multiple layer selections in the Layers palette, hold down either the shift key or the control key and click on the layers that you would like to select (if you're on a Mac, you can use either the shift key or the command key).
Then from the layers palette, drag the layers onto the new document.