Home > Dev > How do you create a Preloader with ActionScript 3 in Flash CS3?

How do you create a Preloader with ActionScript 3 in Flash CS3?

Ok, I’ve searched with Google, I’ve asked on FlashCoders but nowhere got an answer. As far as I can understand it we still have to deal with the old problem in Flash of exporting library assets into frame 1 and using a Preloader. If we simply export the library stuff (and classes) into frame 1 we render our Preloader pretty much useless. But creating a Preloader like in ActionScript 2 obviously doesn’t work anymore.

[ad#ad_content]Usually I’m using a setup like this when creating something in the Flash IDE … my main timeline has three frames, the first only contains the preloader, the second contains a Movieclip that keeps all the linked stuff from the Library and all Classes and the third is where my app starts. Pretty easy, pretty clear.

In ActionScript 3 the MovieClip doesn’t have bytesLoaded and bytesTotal properties anymore but it has a loaderInfo property over which these values can be accessed. If we use these commands in frame 1 but export all our classes in frame 2 (or beyond) we have a problem: The classes required by the Preloader are not there when needed.
A chicken before the egg problem. The classes are in frame 2 but some of them are already needed in frame 1 and if we export all classes into frame 1 we render our Preloader unable to display it’s preload bar early enough at least if we use a lot of classes in our application and unfortunately we cannot put only specific classes into frame 1.
There’s an AS3 tutorial here but it doesn’t mention anything about exporting classes into frame 2.

So how do you do it? Did I miss something in the docs or is the solution so banally obvious but I cannot see it? Or am I totally wrong with my approach and it’s done in a completely different way now? It would be cool to hear some thoughts about this.

Categories: Dev Tags: ,
  1. steff
    May 2nd, 2007 at 18:57 | #1

    You could use the “URLLoader” class ;)

  2. May 2nd, 2007 at 22:07 | #2

    Steff I take it you mean to create an extra SWF that acts as the preloader and loads the main SWF?! Yes that would be a solution but you wouldn’t want to have an extra SWF as a preloader for everything you do in Flash.

  3. Daniel
    May 7th, 2007 at 12:49 | #3

    Steff, I believe that they are functions now. getBytesLoaded() and getBytesTotal().

    This should give you a % of loaded bytes….

    Math.round(_root.getBytesLoaded()/_root.getBytesTotal()*100);

    -=Daniel=-

  4. May 7th, 2007 at 13:35 | #4

    Daniel, in AS3 there are no getBytesLoaded() and getBytesTotal() functions anymore (see AS2 migration). These are now properties of the URLLoader class. Hence the problem with classes not being in frame 1.

  5. carnage
    May 8th, 2007 at 21:05 | #5

    could we somehow use setInterval, so the main timeline will have only one frame?

  6. Charlie
    May 11th, 2007 at 02:17 | #6

    I want to know how to do a preloader in as3, could someone post a download for a .fla with a working preloader in CS3 please

  7. May 12th, 2007 at 04:56 | #7

    I think that there is no way to build preloader in as3. For example when I embed an mp3 into swf, events (progress and complete) are lunched only after the hole swf is downloaded. So the only way is create swf that will load the main swf. There is another way, but I can not implement it in pure as3. As we know there is self preloder in flex…so it should be in as3, but flex is using something that is called progressive layout. It is used to load and initialize every part of swf (f.e. componets)using queque…how? i still can not figure that out

  8. May 12th, 2007 at 12:16 | #8

    qzim, Keith Peters figured out how to create a preloader in pure AS3.0 similar like in Flex2 …. http://www.bit-101.com/blog/?p=946 … it works by creating a factory class which acts as the preloader. This way the factory class goes into frame 1 and your main class into frame 2. The important thing to be noted there is that the factory class will become root. It’s a bit confusing at first but it works. Though if I use this method in Flex Builder I always get unused CSS tag warnings from the compiler, even though I don’t use any CSS! Very strange, might be a Flex bug.

  9. Psykovsky
    May 14th, 2007 at 02:31 | #9

    Every display object now has loaderInfo parameter.
    so for root (or stage) you can use:
    root.loaderInfo.bytesLoaded();
    root.loaderInfo.bytesTotal();

    and also attach the event listener:
    root.loaderInfo.addEventListener(ProgressEvent.PROGRESS, yourFunc);
    root.loaderInfo.addEventListener(Event.COMPLETE, yourFunc);

    Hope it helps :)

  10. May 14th, 2007 at 23:08 | #10

    the preloading-prob is a mess in upcoming flash versions.
    my preloader is probably a beta-solution – i do it like i did
    in flash3 ( first frame looks if all frames have loaded successfully…)

    for example 4 frames. first frame waits till frame 4 has loaded – second
    frame holds all library-linkage stuff and more…

    percentt.text = Math.round( ( framesLoaded/totalFrames ) *100 );

    if ( framesLoaded == totalFrames ) {

    //do some

    }

    it´s not a solution but it works by now…

    pwd

  11. May 15th, 2007 at 01:10 | #11

    pwd, yes either your method or by creating an extra SWF that acts solely as a preloader. I don’t see any other way of having a preloader in a single SWF.

  12. May 19th, 2007 at 03:22 | #12

    here the solution )

    http://dev.etcs.ru/blog/as3/export_in_second_frame_flash_cs3/

    src – http://dev.etcs.ru/flash/export/ExportSecondFrame.zip

    in short

    just use:

    var programClass:Class = loaderInfo.applicationDomain.getDefinition(“Program”) as Class;
    var program:Sprite = new programClass() as Sprite;
    addChild(program);

    instead of NOT working code:
    /*
    var program:Program = new Program();
    addChild(program);
    */

  13. John
    May 26th, 2007 at 01:24 | #13

    Hi Daniel,

    Have you been able to find anything out on the AS 3 Preloader? I’m looking for some guidance too and can’t believe how barren the resources are out there.

    Thanks,

    John

  14. May 28th, 2007 at 03:05 | #14

    Eh there peoples…

    I’m not that up on Flash, heck all I can do are simple animations and such.
    But I was able to get my Adobe CS3 Suite and it has Flash with it, I’m coming from Flash MX and hadn’t used that for about 4 years, but I’m in the same boat.
    I’m doing a new site but need to know how to load ONE simple image inside the actual FLV or SWF itself.
    If anyone figures this out I would greatly appreciate the help.

    -Gibb-
    gibbous_w@hotmail.com

  15. May 28th, 2007 at 03:07 | #15

    Ouhh right one more thing. All I want to create is a simple spinning ball, no text or numbers. Just a little circle / ball that spins while the image is loading.

  16. giantsteps
    May 28th, 2007 at 09:20 | #16

    Den Ivanov –

    I looked at your sample, but it appears to be a version of the three frame variety where AS classes are exported on frame 2 and the app starts on frame three.

    I’m not sure I understand the issue you are addressing here? Thanks for the sample.

    Peter

  17. May 28th, 2007 at 15:59 | #17

    2giantsteps

    No, this example demonstrates, how to create a preloader same as old AS2 practice. You don’t need to make three frames (just third frame doesn’t contain clip with embedded content, nothing more), you can start app at second frame.

    But, we have a problem: if you have hand drawn clips (i.e. tween animation), when you export classes of these clips to second frame and place it’s contents to this frame, then try to create hand drawn class (new MyHandDrawnClass()) in second or third frame, the class creates, but it hasn’t any contents (animation, etc.). I dunno why. This example demonstrates, how to solve this problem.

    Sorry for my english :)

  18. giantsteps
    May 29th, 2007 at 02:25 | #18

    Oh ok – I think I understand. I hadn’t run into this problem yet.

    Looking at your example, I am wondering if your program class had simply failed to initialize in time to run the code in your constructor?

    Did you try listening for the init event as in the code below? I think you might have to extend MovieClip rather than sprite or import Loader and Loaderinfo, but I’m not sure.

    public function Program() {
    super();
    this.loaderInfo.addEventListener(Event.INIT, initApplication);
    }

    public function initApplication(myEvent:Event):void {
    x = 50;
    y = 50;
    var box:Box = new Box();
    var star:Star = new Star();
    var another:AnotherClass = new AnotherClass();
    star.y = 100;
    star.x = 100;
    addChild(box);
    addChild(star);

    }

  19. May 29th, 2007 at 02:50 | #19

    No, it isn’t important, when you trying to create Box and Star classes, their contents willn’t shown anyway. You need to use getDefintion method to create Program class instead of basic creation. Why is it so, i don’t know.

  20. May 29th, 2007 at 23:37 | #20

    Psykovsky’s solution (root.loaderInfo.bytesLoaded();) works fine for me :D
    thanks, btw

  21. June 9th, 2007 at 03:15 | #21

    I found that adding a 200 millisecond delay after the Complete Event allowed me to create new classes. However, what I also found is that if you set classes to load in frame 2 none of the class linked objects on the stage work. Flash comes up with errors saying that it can’t convert the class MovieClip to class .
    This really does look like a bug in CS3. Given that 90% of flash projects need a preloader Adobe needs to sort this out

  22. Drew
    June 20th, 2007 at 03:57 | #22

    Den Ivanov, you are a life saver!

  23. June 20th, 2007 at 04:21 | #23

    2Drew, thanks :) Den Ivanov just informs about my solution :D

  24. LEE
    July 24th, 2007 at 08:04 | #24

    It’s VERY disappointing that Adobe doesn’t take this style of preloading a Flash app into account, and provide a more intuitive solution….

    ….but it is Adobe, they’re always too busy for perfection!

  25. LEE
    July 24th, 2007 at 08:15 | #25

    right about now I just despise Adobe….

  26. July 30th, 2007 at 05:11 | #26

    I created a preloading package (very simple) in AS3. It gives a pretty basic understanding of how the new progress events and such work in AS3.

  27. July 30th, 2007 at 05:12 | #27

    Forgot to post the link…. DOH!!!!

    http://sd-dezign.com/blog/?page_id=10

  28. August 23rd, 2007 at 16:00 | #28

    if someone want some more info about preloading; A few months back I have written two tutorials covering the process in AS 3: http://newmovieclip.wordpress.com/2007/03/14/preloader-in-flash-cs3-actionscript-30-way/
    Enjoy ;-)

  29. December 28th, 2007 at 22:37 | #29

    I’m still looking for a solution, and I found this:

    http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000818.html

    It *may* work… I’m not sure.

  30. December 28th, 2007 at 22:46 | #30

    NAH, everything got screwed up when I changed the class exports to frame 2…

  31. dave
    January 21st, 2008 at 02:59 | #31

    wow. after much searching, denis has the best example of exporting classes with graphics attached from inside the library. This example is illustrating how if you normally just drag instances on the export frame they would be availiable to be instantiated by the “new” keyword and then attached with addChild(), this method still creates an instance of the class, but no graphics that were either drawn in or embedded with external assets. its definetely a work around, but it definetely works! Thanks DENIS.

  32. dave
    January 21st, 2008 at 03:47 | #32

    Another way to preload your classes is same as AS2, putting exports on second frame, waiting til loaderInfo.bytesLoaded==loaderInfo.bytesTotal, then playing to export frame. If you create a MovieClip call MAIN or ROOT or whatever and attach a script, you can use this as your “document class”, you can then create instances with library attachment using the “new” keyword and the graphics and everything in them will show up properly. Its a little bit of a hack because you’re putting everything in another Movieclip…but I dont see a problem arising from this solution because its just another display object container one child down from the maintimeline anyway.

    the source is here.

    http://www.odysseywave.com/as3_preload/example.zip

  33. An Example
    March 18th, 2008 at 07:02 | #34

    I made a movie clip with 100 frames with a shape tween progressing through it. I exported it to action script and gave it the class “preloadBarClass”.

    stop();

    addEventListener(Event.ENTER_FRAME, preloadNow);
    var preloadBar:preloadBarClass = new preloadBarClass();

    //I build how I want the frame to look first, take note of all
    //the variables I need, then clear the frame.
    preloadBar.x = 25.4;
    preloadBar.y = 164.8;

    addChild(preloadBar);

    function preloadNow(event:Event) {
    var prebytesTotal:Number = stage.loaderInfo.bytesTotal;
    var prebytesLoaded:Number = stage.loaderInfo.bytesLoaded;
    var preAverage:Number = Math.round((prebytesLoaded/prebytesTotal)*100);
    trace(preAverage +”% loaded.”)
    preloadBar.gotoAndPlay(preAverage);
    if (prebytesLoaded >= prebytesTotal) {
    gotoAndStop(2);
    removeEventListener(Event.ENTER_FRAME, preloadNow);
    removeChild(preloadBar);
    }
    }

  34. An Example
    March 18th, 2008 at 07:03 | #35

    edit: that code goes in frame 1 on the main timeline.

  35. Boterkoek
    April 10th, 2008 at 05:22 | #36

    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 execute from within the Document Class, in external .as file?

    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%

  36. May 6th, 2008 at 13:16 | #37

    I think that there is no way to build preloader in as3.

  37. Wes
    June 7th, 2008 at 01:50 | #38

    put this in the first frame of your SWF. The rest of the movie on frame 2 and above

    //Actionscript 3
    stop();
    this.addEventListener(Event.ENTER_FRAME,testInterval);

    function testInterval(e:Event):void{
    var nLoadedBytes:Number = loaderInfo.bytesLoaded;
    var nTotalBytes:Number = loaderInfo.bytesTotal;
    //trace (nLoadedBytes / nTotalBytes * 100)
    percent.text = Math.round(nLoadedBytes / nTotalBytes * 100)+ “% complete”;
    //trace (nLoadedBytes / nTotalBytes * 100)
    if (nLoadedBytes >= nTotalBytes) {
    trace(“load complete”);
    this.removeEventListener(Event.ENTER_FRAME,testInterval);
    play();
    }
    }
    //End

  38. June 10th, 2008 at 22:23 | #39

    I don’t know if this will help anyone, but if you are using a document class in Flash CS3 IDE, the document class (main class) has an instance of a LoaderInfo attached to it.

    so for example, if my document class was MyDocumentClass:

    public function MyDocumentClass() {

    this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);

    }

    and then put your preloading code in onProgress().

    -Dan

  39. thienhaflash
    June 30th, 2008 at 13:59 | #40

    I searched everywhere, and find no solution, too
    (sight…)

    Same with you, sascha.
    And agree with you, Anime English

    Maybe there’re just no way to load external .as file and set it to export in other frames than frame 1.

    Using another swf to act as the preloader will be the only workaround then…

  40. Dennis
    July 28th, 2008 at 20:43 | #41

    Hey Wes, your solution seems to work fine. What is the problem then? It is clean and simple. Why should one not use Wes’ solution?

  41. Jelle
    August 26th, 2008 at 05:54 | #42

    Because it is not a solution? Every preload example looks like it works but when I but my whole library in it… it first load my library before it preloads.

    Also tried to but my library contents in frame 2 but no solution.

  42. vegeta
    September 24th, 2008 at 13:28 | #43

    thanks wes you are the man

  43. October 28th, 2008 at 00:58 | #44

    Well said.

  44. October 31st, 2008 at 18:07 | #45

    Preloading in AS3 is easier then we have all made it out to be. Simply create a new FLA file that imports your current SWF. You new movie should contain code like the following:

    // Create a new Loader and URLRequest class
    // Look at Flash’s help file to learn more
    var l:Loader = new Loader();
    var request:URLRequest = new URLRequest(“bigMovie.swf”);
    // Now we assign a listener to fire when bytes are recieved which will run a function everytime this happens
    l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loop);
    // Asign a listener and a function to the COMPLETE event to basically start our movie
    l.contentLoaderInfo.addEventListener(Event.COMPLETE, done);
    // Now load your external asset
    l.load(request);
    // Function to handle Preloader updating
    function loop(evt:ProgressEvent):void {
    var perc:Number = evt.bytesLoaded/evt.bytesTotal;
    // I have a text field on frame 1 named percent to show download progress
    percent.text = Math.ceil(perc*100).toString();
    }

    function done(evt:Event):void {
    // We are done preloading so ditch the text field
    removeChildAt(0);
    percent = null
    // Add our loader to the display list
    stage.addChild(l);

    }

    You will of course want to include a Event.ADDED_TO_STAGE listener in there somewhere so your movie can instantiate itself somehow,someway.

    You can thank our good friend Lee Brimelow (www.theflashbog.com) for this one. He has a very in depth video tutorial and I recommend you follow it.

  45. Rex
    December 12th, 2008 at 05:19 | #46

    I think the solution you’re looking for sascha is mostly undocumented, but it exists:

    Use a 3 frame main timeline to load any library assets, explained at:
    http://www.8bitrocket.com/newsdisplay.aspx?newspage=10807

    Here’s the catch. No matter what frame is specified in the publish settings, Flash will always load the following in the first frame: (1) any custom document class (along w/ any classes imported in that document class), and (2) any classes imported on the main timeline (regardless of which frame they’re imported on). The publish setting applies only to classes imported within MovieClips that are children of the main timeline. I tested this myself after reading it here:
    http://summitprojectsflashblog.wordpress.com/2008/10/31/as3-class-export-frame-behavior/

    So that means you have to contain your entire application within a MovieClip on the third frame (if using methods of the first link above). This clip could be assigned a class and treated like the root/document. Any classes you want to use during preloading on the first frame must be put in the real document class, or imported right on the main timeline in the first frame.

    Stupid that preloading is such a problem, but this way you can deploy a single, self-contained swf with a preloader that works and is built with class files instead of messing with timelines and movieclips.

  46. April 10th, 2009 at 04:50 | #47

    Thank you Rex! That’s exactly what I was looking for. I never quite understood “the catch” until now.

  47. April 10th, 2009 at 05:55 | #48

    i had code in my Flash file that had references to “stage” that weren’t working correctly, so here’s my fix.

    i noticed that when you use addChild(), it doesn’t initialize the SWF the same way it would if it were being executed directly (the stage reference gets weird). So I used the ADDED_TO_STAGE event (however this causes the movie to initialize twice!), so I put in a flag to tell it to only initialize the one time and it worked!

    i created a preloader flash movie has this code borrowed from http://www.gotoandlearn.com/play?id=85:

    var l:Loader = new Loader();
    l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loop);
    l.contentLoaderInfo.addEventListener(Event.COMPLETE, done);

    l.load(new URLRequest(“main_content.swf”));

    function loop(e:ProgressEvent):void
    {
    var perc:Number = e.bytesLoaded / e.bytesTotal;
    percent.text = Math.ceil(perc*100).toString();
    }

    function done(e:Event):void
    {
    percent = null;
    stage.addChild(l);
    }

    then in my “main_content” flash file, the document class I contains the following:

    package {

    public class main_content extends Sprite {

    public function main_content() {
    if(stage!=null) {
    // file is running without the preloader
    init();
    } else {
    // file is included by the preloader
    addEventListener(Event.ADDED_TO_STAGE,init);
    }
    }

    public function init(evt:Event=null) {
    if(!inited) {
    inited=true;
    if(stage.numChildren==2) {
    stage.removeChildAt(0);
    stage.addChild(this);
    }
    }
    // everything else here
    }

    }

  48. April 10th, 2009 at 21:52 | #49

    note that in the above example i had to remove the content from the stage and then re-add it to get it to initialize correctly.

  49. laura
    June 20th, 2009 at 16:23 | #50

    There is something here
    http://www.bit-101.com/blog/?p=946
    , about this subject of class methods throwing an error when the mc have not been loaded
    I don´t get it tought

  50. laura
    June 20th, 2009 at 16:26 | #51
  51. July 3rd, 2009 at 23:59 | #52

    Web / Graphics Designer

  52. March 8th, 2010 at 00:17 | #53

    This doesn’t always work…

    stop();

    this.loaderInfo.addEventListener(Event.COMPLETE, initApplication);
    this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, showProgress);

  53. AleksandrRV
    July 2nd, 2011 at 22:35 | #54

    @An Example
    Thank you very much!
    It helped me

  1. October 6th, 2014 at 16:27 | #1
You must be logged in to post a comment.