Apr
07
Internal PreLoading in ActionScript 3
I’m going to walk through the steps of making a preloader for your animation, game, or application and provide easily implemented source files that you can copy and change to fit your own project. Making a preloader in ActionScript 3 is more difficult to figure out then it was in ActionScript 2, but the code itself is not any harder.
To start off, you can access the stage’s bytesLoaded and bytesTotal through it’s loaderInfo.
Once you know that, building a preloader becomes very easy:
import flash.display.MovieClip;
import flash.text.TextField;
import flash.events.*;
public class ClickPopPreLoader extends MovieClip {
var initX:Number;
public function ClickPopPreLoader() {
initX = loadProg_MC.x;
addEventListener(Event.ENTER_FRAME, handleProgress);
}
private function handleProgress(event:Event):void {
var loaded:Number = stage.loaderInfo.bytesLoaded
var total:Number = stage.loaderInfo.bytesTotal
var percent:Number = loaded/total;
// trace(Math.floor(percent*100)+"%");
UpdateProgress(percent);
if(loaded >= total){
removeEventListener(Event.ENTER_FRAME, handleProgress);
/*stage.getChildAt(0) can cause an error message that is
really a warning. Turn off Strict mode in "Publish Settings"
and it will compile just fine.*/
stage.getChildAt(0).gotoAndPlay(‘begin’);
}
}
private function UpdateProgress(prog:Number):void {
loadProg_MC.x = initX - (initX * prog);
output_TF.text = String(Math.floor(prog * 100)+"%");
}
}
}
The code is so short I would feel silly cutting it up.
The code above would be a class file for a MovieClip that contains another MovieClip called loadProg_MC that acts as a mask for some kind of load bar (in my example it’s unmasking the glow behind the words “Click Pop Media”). The MovieClip would also have a TextField called output_TF to display the % loaded.
Notice that I’m using the ENTER_FRAME event rather then the PROGRESS event. You really could use the PROGRESS and COMPLETE events, but I’ve heard that it doesn’t work consistently in IE6 on PCs (supposedly that has been fixed in Flash Player 9.0.115). I haven’t really checked this myself because I don’t have Internet Explorer 6, but I just take their word for it because ENTER_FRAME works just as well.
Once you get the stage.loaderInfo what you do with it and how you display the load progress is up to you. That’s actually not the part that raises questions for most people. What usually happens is that they will add all the right code and make a really good preloader animation and then when they test it out… the preloader doesn’t show up until AFTER everything is loaded.
The problem that we run into is that Flash Player loads a movie starting with frame one and then works its way up. Although you may only have your preloader on frame one you need to take a look at the “linkage” of each of your library items.

The checkbox, which by default is selected, called “Export in first frame” needs to be unchecked for as many, if not all, of your library symbols (especially larger items like sounds and music). “Export in first frame” means that until this item is loaded the first frame can’t play. Thus, if everything is exported in the first frame then your preloader won’t have a chance to show anything loading before it’s already done.
This leads to another problem though! If you are creating instances of your library symbols dynamically using ActionScript and that code loads before the symbol does, then you will get runtime errors. This isn’t really a problem if you have a pure animation without any code. For a game though, avoiding this little problem is messy, but it can be done easily enough and without being noticed by the end users.
What you have to do is, in a frame BEFORE any of your main code, create one instance of each library item that is going to be instantiated dynamically… but still after your preloader. A good practice would be to have your preloader on frame 1 and then all your instances on frame 2. When your preloader is done (and maybe the play button is clicked) it will jump PAST frame 2 and go straight to the beginning of your animation/game/app.
————————————————————————————-
For those of you who either don’t want to turn off strict mode or want to avoid OOP (Object Oriented Programming), here is the same code I gave you before, but modified to reside on the stage instead of in a class.
addEventListener(Event.ENTER_FRAME, handleProgress);
function handleProgress(event:Event):void {
var loaded:Number = stage.loaderInfo.bytesLoaded
var total:Number = stage.loaderInfo.bytesTotal
var percent:Number = loaded/total;
// trace(Math.floor(percent*100)+"%");
UpdateProgress(percent);
if(loaded >= total){
removeEventListener(Event.ENTER_FRAME, handleProgress);
gotoAndPlay(‘begin’);
}
}
function UpdateProgress(prog:Number):void {
PreLoader.loadProg_MC.x = initX - (initX * prog);
PreLoader.output_TF.text = String(Math.floor(prog * 100)+"%");
}
You can also make a document class if you wanted (for those who like OOP, but still want to keep Strict mode for some reason), but I’m not going to get into that here.
As promised, here is the source files to a working preloader: ClickPopMedia Preloader
There is instructions all over the place within those files.
Tags: PreLoader




















April 8th, 2008 at 12:09
Will this technique work using the Document Class?
April 8th, 2008 at 12:27
Sure. If you wanted to do this with the document class I would suggest putting all the preloader code in the document class.
ClickPopMediaThe code would look like a combination of my first and second examples. Where you would have PreLoader.loadProg_MC.x and just gotoAndPlay(’begin’), but everything would be in methods. Also you would have to be careful about creating instances of library symbols before they are loaded.
For my one project I turned my entire movie into a MovieClip and my document class became that MovieClip’s class. Then I was safe to only have the preloader code in my container’s document class and I would have my real application (as a movieclip) on the main timeline around frame 3.
April 9th, 2008 at 15:05
Is there any way to avoid the ‘export on first frame’ issue, using the strick/OOP as3 mode, where the main timeline has nothing more then 1 empty frame. And all the code of preloader and game in the Document Class?
I have tried to set the publish setting ‘export class’ on 2 already (publish->flash->settings..) but the preloader does not get any chance to show up any earlier then at 100% :/
April 9th, 2008 at 16:43
You are still having the problem of your library being exported to the first frame. I know it’s a little annoying, and you should be fine if your code is exported on frame 2, but you need your library to be loaded on frame 2 as well. That way the preloader is loaded and starts playing before anything else starts loading.
ClickPopMediaApril 10th, 2008 at 3:46
Thanks Paul,
Is there any other way to load instances of the library on a second frame, without placing the clips,musics on the second frame of the main time-line? Its a bit annoying that the main time-line (_root) is no longer usable.
I also tried to uncheck the ‘export on first’ prop for the musics, but it will result in runtime errors the moment a new instance of the resource was created in actionscript.
April 10th, 2008 at 10:33
I haven’t been able to find a way to load things on a specific frame (except the first frame) without placing the item on that frame.
What I do, and I think I’ve mentioned this before, is I will make my application with a Doc Class, but without the preloader. Then when it’s done and working, I will convert the whole thing to a MovieClip on frame 3 and THEN add my preloader.
ClickPopMediaIn a sense it’s like I’m creating a container movie to load my external swf, but I’m keeping it all contained so as to avoid external loading. The one downside is that you have to try and avoid using any reference to the stage (except maybe for event listeners like keyboard events).
April 12th, 2008 at 21:22
Looks good, I’m planning on jumping into Flash CS3 in the coming weeks so perhaps this will come in handy very shortly! I’ll post a link to it on my blog.
April 15th, 2008 at 22:42
Awesome! Thanks.
If you ever have any questions or requests for a tutorial, let us know and we will see what we can do.
ClickPopMediaMay 14th, 2008 at 8:16
good, thanks
May 14th, 2008 at 8:19
goo, thanks
May 26th, 2008 at 15:48
i’m attempting to move the mask to a final .x of 420. to accomplish this I’m trying to re-write part of the AS3 so that it includes a formula which will move my mask to a final .x of 420 upon total bytes loaded equaling 100%:
below is the code I’m using. I receive this message when testing my movie:
ReferenceError: Error #1065: Variable finalProg_MC is not defined.
at ClickPopPreLoader()
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()
at flash.display::MovieClip()
at ClickPopPreLoader_fla::MainTimeline()
What I’ve done is create an instance of a symbol:”finalX” and given it an .x of 420. Then i’ve tried to use this .x as part of the formula for moving the mask.
I’m trying to update the progress of my mask based on the below function:
loadProg_MC.x = finalX + (initX - (initX * prog));
}
Any suggestions. Below is the complete copy and paste AS3 I’m using.
-shalom
May 26th, 2008 at 21:54
clint, You are getting this (Error #1065: Variable finalProg_MC is not defined.) because you are either misspelling the MC’s name or it needs to be accessed through its parent (i.e. loadProg_MC.finalProg_MC.x).
Also, you are using a formula:
ClickPopMedialoadProg_MC.x = finalX + (initX - (initX * prog));
that might not do what you want it to do… If I wanted to move a mask in from the left to right I would use:
loadProg_MC.x = initX + ((finalX - initX)* prog);
May 29th, 2008 at 1:56
thank you!
June 6th, 2008 at 6:07
Hi. Having read lots of AS3 preloading articles, I still have a problem. Here’s the setup:
- My movie has 3 frames. The first one is blank, the second contains an instance of every one of my library items that need linkage but aren’t exported in first frame. I’ve done this process for years.
- I export my classes in the 2nd frame, the same frame that I export my library assets.
- I’m using a document class called Preloader, which acts as the preloader. Once it’s done waiting for bytesLoaded to hit bytesTotal, it does gotoAndStop(3), though I’m not sure I need to do that. It then does: new Application(). The Application class is my game.
- I have, among other similar elements, a class, MenuButton, which has a library instance to go with it. Or, if you prefer to think of it the other way round, I have a MenuButton symbol in the library, whose class is contained in my class library that gets exported in frame two. In the linkage settings for my MenuButton, I have its Class as mygame.menu.MenuButton, and Base Class as flash.display.MovieClip. Export for ActionScript is the only check box checked.
My problem is that, in my Application class, when I go to create a new MenuButton (this is on frame 3 of the timeline), it’s not attaching the MenuButton from the library. The MenuButton still exists - but it’s only in the form of the AS file class - it doesn’t have the graphical elements of the library item.
I first noticed this after a lot of confusion thanks to me trying to address a dynamic text field in my MenuButton library symbol. In my MenuButton.as constructor, I try to address this["iTF"], and it wasn’t working. This is because (and this is the way I imagine it, anyway) this["iTF"] gets added to the class when it ‘merges’ with the library symbol of the same linkage name.
So, I then thought that maybe I should export the classes before the library assets, or vice versa - export classes on 2, library instances on the stage on frame 3, and ‘run the application’ on frame 4, that kind of thing. Neither combination of this seems to fix the problem, though.
June 6th, 2008 at 11:25
Well Shaun, it sounds to me like you aren’t new to coding or anything. I figure anything I suggest may or may not work and this is going to take a little discussion.
If I may, I think we should bring this up in the forums over at http://www.actionscript.org/forums/forumdisplay.php3?f=75
(We are still working on our own forums, but they will be up soon too)
If and when you do start a new thread there, send me a PM @ TomMalufe (my alias on actionscript.org). That is a great forum and site for AS questions and I go there all the time answering questions. It’s also the place where I originally learn how to make a preloader back when I was still coding in AS2.
I would think that you’ve already tried this, but I don’t usually export my classes in any frame except the first and I’ve never had a problem (exactly) like this.
ClickPopMediaJune 6th, 2008 at 12:22
Hi Paul, thanks for the reply - hopefully you’ll see this and continue the discussion. Go ahead and bring it up on actionscript.org if you want!
You’re right, I’m not new to coding.
The problem with exporting my classes in the first frame is that they then add to the non-preloadable portion of the file, don’t they? What if I have tens or hundreds of classes? That’s why I want to load them all in a later frame.
:)
June 30th, 2008 at 14:29
Hi Paul,
I am pretty new to coding and I am having a problem when I use your preloader. I have a Document Class (Main.as) set up. I set up the frames like you suggested up top. My preloader is on the first frame with a class-name of PreLoader. I have a few MovieClips that are not being exported on frame three (along with some that are being exported).. The strange thing is that some of the clips that aren’t being exported are null when the document class tries to access them… Is this some sort of timing issue with what gets loaded when?
Thanks!
August 20th, 2008 at 7:41
Hi Flashers–
I keep gettign this error:
”
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at MC_internal_class_fla::MainTimeline/UpdateProgress()
at MC_internal_class_fla::MainTimeline/handleProgress()
”
Has anyone found or know of a solutions for this? What does this mean?
September 4th, 2008 at 10:57
Hi.
I am using the “internal” preloader and I am having a problem with the movie starting to play before it jumps to a specific frame. How can I get the preloader to keep checking to see if all frames are loaded before it plays a specific frame?
September 5th, 2008 at 9:37
I’ve run into this problem before… or more specifically, someone else did and they also asked for help.
ClickPopMediaAs I recall the flash player ignored all stop() commands on frame 1. It was the darnedest thing and I still don’t understand why it does that. I believe our solution was to put a stop() on the second frame and push everything back an extra frame while stretching any preloader graphics out to the second frame.
If you have a lot of graphics to load on the second frame then this wouldn’t be a problem.
November 20th, 2008 at 16:36
Hi
I tried my own code for the preloader but kept getting the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at crxPreLoader/::handleProgress()
Since it didn’t seem to be working, I decided to try your code and hopefully I would understand what was wrong with mine.
Well I copy-pasted your code into a new as file, commented all references to loadProg_MC and output_TF and then saved it in the same folder as my fla, which is empty and only has one line of code:
var preloadTest:ClickPopPreLoader = new ClickPopPreLoader()
When testing the file, I get the same error on ENTER_FRAME event:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at ClickPopPreLoader/::handleProgress()
If I replace the whole code at handleProgress function for a trace (like //trace(”loading”)) it works but of course, retrieves no loading info.
I am forced to think that the problem is in referrencing the stage at “stage.loaderInfo.bytesLoaded” but can’t fgure out why.
It seemed to work fine for you as well for others in this thread, so I don’t get it. What’s wrong? I’m using Flash CS3 Professional.