A Flash Developer Resource Site

Results 1 to 17 of 17

Thread: Loading a SWF and calling a method in it

  1. #1
    Game Developer
    Join Date
    Apr 2001
    Location
    Canada
    Posts
    292

    Question Loading a SWF and calling a method in it

    I have a preloader which loads a swf file, and once it's fully loaded it, it calls a function in it.

    However, it doesn't seem to work. I get an error basically saying the function doesn't exist.

    Here is what I do in the preloader :

    Code:
    var l:Loader = new Loader();
    l.contentLoaderInfo.addEventListener(Event.COMPLETE, done);
    l.load(new URLRequest("http://www.mywebsite.com/game.swf"));
    
    function done(e:Event):void
    {
    	mainSWF = MovieClip(l.contentLoaderInfo.content);
    	mainSWF.init(userid,username);
    }
    game.swf has no code on the main timeline. It has it's document root set to "Game".

    My Game.as file looks like this :

    Code:
    package {
    	import flash.display.MovieClip;
    	import flash.display.Sprite;
    	
    	public dynamic class GameBoard extends Sprite {
    		public var mpLobby:MovieClip;
    		
    		public function GameBoard() {
    		}
            
    		public function init(userid:String = "",username:String = ""):void {
                         trace("it worked");
    		}
    	}
    }
    When I run the preloader, it sucessfully loads the game.swf file and then attempts to run the init() function inside it, but then dies with this error :

    Code:
    ReferenceError: Error #1069: Property init not found on Game__Preloader__ and there is no default value.
    	at preloader_fla::MainTimeline/done()
    Any ideas?

    Thanks so much!

    Ryan

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    It looks like your Game.swf's document class is not actually Game, but some sort of preloader class. Judging from the name Game__Preloader__, this was probably auto generated. How did you create Game.swf?

  3. #3
    Game Developer
    Join Date
    Apr 2001
    Location
    Canada
    Posts
    292
    Ok, I changed a few filenames in my original post as to not complicate things.

    In my example Game.swf is actually MPLobby.swf that has a document class of "GameBoard". So instead of game.as I have GameBoard.as.

    I created MPLobby.swf by compiling my MPLobby.fla.

    So my preloader loads in the MPLobby.swf file and then tries to call the init() method in it's document class.

    The actual unedited error I get is :

    Code:
    ReferenceError: Error #1069: Property init not found on GameBoard__Preloader__ and there is no default value.
    Not sure where it's getting GameBoard__Proloader__ from. The preloader itself is called preloader.swf.

    I hope I explained that properly.

    Thanks for you help. Greatly appreciated!
    Last edited by Sparticus007; 11-02-2011 at 11:40 AM.

  4. #4
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,136
    Generally, load the remote SWF with a Loader, wait for it to dispatch INIT, and then use the loader.contentLoaderInfo.applicationDomain.getDefi nition("className") as Class to load the class into your current application domain where you can instantiate it. You can't call MainSWF.init in this case, because MainSWF is being typed as a MovieClip, and movieclips don't have functions. You need to treat GameBoard as a class that's part of the SWF applicationDomain you just loaded. So:

    Code:
    var l:Loader = new Loader();
    l.contentLoaderInfo.addEventListener(Event.COMPLETE, done);
    l.load(new URLRequest("http://www.mywebsite.com/game.swf"));
    
    function done(e:Event):void
    {
    	var GameBoard:Class = this.l.contentLoaderInfo.applicationDomain.getDefinition("GameBoard") as Class;
    	var gameBoard:* = new GameBoard(); //or if you make it a singleton, call init as a static function.
    	gameBoard.init();
    }
    The Strike Agency
    http://www.theStrikeAgency.com

    StrikeSapphire -- The Original Bitcoin Casino
    https://strikesapphire.com
    (not available in the US)

  5. #5
    Game Developer
    Join Date
    Apr 2001
    Location
    Canada
    Posts
    292
    Thanks joshstrike. Very close to having it working.

    However, after the SWF has downloaded if I try and do :

    Code:
    var GameBoard:Class = this.l.contentLoaderInfo.applicationDomain.getDefinition("GameBoard") as Class;
    it reports this error :

    Code:
    ReferenceError: Error #1065: Variable GameBoard is not defined.
    Oddly enough if after the SWF has downloaded I wait 100 milliseconds then try and get the definition, it works.

    Do i need to wait for another event to fire before I can start accessing the methods in the SWF?

    Thanks!

  6. #6
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,136
    Ah, sorry! My mistake. The listener on contentLoaderInfo should be for Event.INIT, not Event.COMPLETE. Complete fires when the load is done. Init fires when the classes are accessible.
    The Strike Agency
    http://www.theStrikeAgency.com

    StrikeSapphire -- The Original Bitcoin Casino
    https://strikesapphire.com
    (not available in the US)

  7. #7
    Game Developer
    Join Date
    Apr 2001
    Location
    Canada
    Posts
    292
    Hmm, I tried that.... but I read that INIT actually fires before COMPLETE.

    Read this somewhere :

    Code:
    A very similar event to the Event.COMPLETE is the Event.INIT which is triggered when the external asset is ready to be used, whether fully downloaded or not

  8. #8
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,136
    That's strange. I do this all the time...although usually for Library classes like fonts. INIT is supposed to be definitive of the first frame of the SWF being ready to use. Within the SWF you're loading, are you sure these classes are exported for Actionscript, imported into your document class, or otherwise accessible, on Frame 1? If they weren't accessible to the constructor of your SWF document class, I could see that being a problem.
    The Strike Agency
    http://www.theStrikeAgency.com

    StrikeSapphire -- The Original Bitcoin Casino
    https://strikesapphire.com
    (not available in the US)

  9. #9
    Game Developer
    Join Date
    Apr 2001
    Location
    Canada
    Posts
    292
    The FLA that created the swf that is being loaded has no code in it at all. Just some images/assets in the library. I do set the Document Class to "GameBoard".

    There is a Gameboard.as file.

    I added a bunch of trace statements, here is the order that stuff appears to happen in when the download starts :

    1.) First INIT fires
    2.) Then the download COMPLETE fires
    3.) Then the trace statement in the constructor for GameBoard happens

    So, what explains why I need to wait 100 milliseconds or so to access the gameBoard class. Apparently at COMPETE it's constructor hasn't been run.


    I doubt it has anything do do with it.... but I do get the error :

    Warning: An ActionScript 1.0/2.0 SWF file has loaded an ActionScript 3.0 SWF; code in the ActionScript 3.0 SWF will not run.
    I have double checked I do not have any AS1 or AS2 anywhere. From what I am reading online the error has somethign to do with :

    Code:
    this.l.contentLoaderInfo.applicationDomain.getDefinition("GameBoard") as Class;
    Which makes sense cause it starting happening after I added that code.

  10. #10
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,136
    You shouldn't be getting that error at all unless your Export (Actionscript) settings are set to AS2 on the file that's doing the loading.

    Something odd about this.

    Since it is your document class (I didn't really absorb that), just for laughs, try this (not very nice) way of calling your public init function when you get the INIT event:

    Code:
          trace (this.l.contentLoaderInfo.content); //should in no case be null.
          this.l.contentLoaderInfo.content["init"]();
    The Strike Agency
    http://www.theStrikeAgency.com

    StrikeSapphire -- The Original Bitcoin Casino
    https://strikesapphire.com
    (not available in the US)

  11. #11
    Game Developer
    Join Date
    Apr 2001
    Location
    Canada
    Posts
    292
    Ok, I added that code the function that gets called when INIT fires. I get :

    [object GameBoard__Preloader__] <---- trace
    ReferenceError: Error #1069: Property init not found on GameBoard__Preloader__ and there is no default value.
    at preloader_fla::MainTimeline/onInit()

  12. #12
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,136
    And back to that weird __Preloader__ ...huh. Okay, I think I found your problem. (Gotta love duckduckgo!) I don't develop in CS5, I still code in Flex 3 =) but check this out:

    http://www.stevensacks.net/?s=actionscript

    Seems like CS5 Text Layout Framework textfields do something screwy before load, making it impossible to access frame1 functions in the document class. Seems like it's a major issue (43 comments)... one workaround seems to be to add it to the display chain and wait for an ADDED_TO_STAGE, which is kind of absurd. Personally I'd say take out your textfields and generate them in code.
    The Strike Agency
    http://www.theStrikeAgency.com

    StrikeSapphire -- The Original Bitcoin Casino
    https://strikesapphire.com
    (not available in the US)

  13. #13
    Game Developer
    Join Date
    Apr 2001
    Location
    Canada
    Posts
    292
    Hmm, I did some reading in other forums and someone said that AS1/2 error can happen if you call your document classes constructor twice.

    I do this :

    Code:
    var GameBoard:Class = this.l.contentLoaderInfo.applicationDomain.getDefinition("GameBoard") as Class;
    var gameBoard:* = new GameBoard();
    If I comment out the second line, the as1/2 error goes away, and the trace statement in the GameBoard constructor still happens.

    So I think I'm getting closer, however, I tried calling :

    Code:
    GameBoard.init();
    but it can't find the init() function.

  14. #14
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,136
    No man. That __Preloader__ thing is completely weird and is a sign of a CS5 bug. That class should be accessible by INIT. Something about the CS5 textfields causes the loaded file to hang in this "preload" state beyond the proper time. The blog post said it took up to five frames. This is an Adobe bug.
    The Strike Agency
    http://www.theStrikeAgency.com

    StrikeSapphire -- The Original Bitcoin Casino
    https://strikesapphire.com
    (not available in the US)

  15. #15
    Game Developer
    Join Date
    Apr 2001
    Location
    Canada
    Posts
    292

    resolved

    That sucks. lol

    I tried your suggestion of waiting for the downloaded movieclip to be ADDED_TO_STAGE and that works!

    Sure, it's more of a workaround to get around Adobe's bug.

    Well, I really appreciate your help tracking this down. Looking back at all my questions I've asked on this forum over the years you were the one that answered most of them. The community and myself are greatful for all your help.

    Thanks!

  16. #16
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,136
    Hah! Well, you must ask good questions, because I only show up every other month, and I ignore the easy ones

    Glad it's solved. I learned something interesting, too. Another reason not to upgrade to CS5. Cheers!
    The Strike Agency
    http://www.theStrikeAgency.com

    StrikeSapphire -- The Original Bitcoin Casino
    https://strikesapphire.com
    (not available in the US)

  17. #17
    Junior Member
    Join Date
    Sep 2015
    Posts
    1
    Use "ProLoader" instead of "Loader" . This problem will be solved. I tested it.

    ProLoader delivers a consistent loading experience. It is especially helpful with SWF files that use RSL preloading. For example, SWF files that use TLF text use RSL preloading by default. In these cases, ProLoaderInfo delays sending the INIT or COMPLETE events until RSL preloading has completed and real content is available. As a result, the content property can then access real content. ProLoader also helps you avoid other problems, such as:

    *Extra addedToStage and removedFromStage events
    *Content that is loaded to the wrong parent on frame one (applies to content published to Flash Player 10.2 or higher using Flash Professional CS5.5 or higher).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center