A Flash Developer Resource Site

Results 1 to 4 of 4

Thread: Load external Swf and go to a particular frame [AS3]

  1. #1
    Junior Member
    Join Date
    May 2009
    Posts
    11

    Load external Swf and go to a particular frame [AS3]

    Hi everyone,

    I have an empty swf (container) where my external swfs get loaded and unloaded. I have two swfs - Acitivity 1 and Activity 2 (each contain an activity to complete on several frames).

    The user is able to click back from activity 2 to activity 1, but they get to the beginning of the activity instead of where they were last (last frame on swf). I would like to be able to click the back button and go the last frame on the swf being loaded.

    So, how do I load an external swf and then go to the last frame in it? But I dont want this to happen everytime I go to activity 1. Only when you click the back button from activity 2.

    Thanks guys.

  2. #2
    Total Universe Mod jAQUAN's Avatar
    Join Date
    Jul 2000
    Location
    Honolulu
    Posts
    2,429
    The simple answer is to use an MVC pattern but since that's probably really confusing I'll try a condensed answer.

    1. You need a central point to store data. If you're writing code on frame 1 of the main timeline of the main movie, use that, if you're using a document class for the main movie, use that.

    2. You need to come up with descriptive names for the different "states" your movie. Something like, var lastMovie or var previousActivity and currentMovie or currentActivity or what ever makes sense to you. Since these variables/properties will be centralized, you can use them to help decide what to do when any activity is loaded.

    3. You are likely using a Loader object to load the .swf's with something like:
    var loader:Loader = new Loader();
    loader.load(new URLRequest("mySwf.swf"));
    But Loader objects also have a property that contains information about the .swf being loaded and tracks the progress of the loading called .contentLoaderInfo. Since you can't control the playhead of a loaded .swf until it's fully loaded, you need to assign an event listener to .contentLoaderInfo that listens for COMPLETE like this.

    PHP Code:
    var loader:Loader = new Loader();
    loader.contentLoaderInfo.addEventListener(Event.COMPLETEonCompletefalse0true);
    //onComplete is the name of a function you create that gets run
    //when, you guessed it, the load is complete.
    //Then load as normal.
    loader.load(new URLRequest("mySwf.swf"));

    //here, you react to the completion of the load and use your state variables
    //to decide what to do
    function onComplete(event:Event):void{
      
    //here you write code that basically says
      //if the last movie was activity 2 and the current movie is activity 1,
      //tell the target of the event object passed to this function to gotoAndPlay(50)
      //or whatever frame you want

    4. You need to have the buttons that change movies also change the value of you state variables so that when onComplete() runs, you have an accurate description of the state of your movie.
    Last edited by jAQUAN; 11-10-2009 at 09:46 PM.

  3. #3
    Junior Member
    Join Date
    May 2009
    Posts
    11
    Sorry I didn't post earlier - but this is my code (.as)

    Code:
    package {
    	
    	import flash.display.MovieClip;
    	import flash.events.Event;
    	import flash.events.IOErrorEvent;
    	import flash.display.Loader;
    	import flash.net.URLRequest;
    	
    	public class MovingAheadMain extends MovieClip {
    		
    		private var _loader:Loader;
    		private var _isLoaded:Boolean;
    		
    		public function MovingAheadMain() {
    			trace("MovingAheadMain Created!");
    			_isLoaded = false;
    			
    			loadClip("first.swf");
    		}
    		
    		public function loadClip(url:String):void {
    			trace("loadClip called ", url);
    			if (_isLoaded) {
    				unloadClip();
    			}
    			
    			
    			//load
    			var req:URLRequest = new URLRequest(url);
    			_loader = new Loader();
    			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onClipLoaded);
    			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onClipError);
    			_loader.load(req);
    		}
    		
    		public function unloadClip():void {
    			trace("unload clip");
    			_loader.removeEventListener(Event.COMPLETE, onClipLoaded);
    			_loader.removeEventListener(IOErrorEvent.IO_ERROR, onClipError);
    			
    			removeChild(_loader);
    			_loader.unload();
    			_loader = null;
    			
    			_isLoaded = false;
    		}
    		
    		public function onClipLoaded(e:Event):void {
    			_loader.removeEventListener(Event.COMPLETE, onClipLoaded);
    			_loader.removeEventListener(IOErrorEvent.IO_ERROR, onClipError);
    			
    			
    			addChild(_loader);
    			
    			
    			_isLoaded = true;
    		}
    		
    		public function onClipError(e:IOErrorEvent):void {
    			_loader.removeEventListener(Event.COMPLETE, onClipLoaded);
    			_loader.removeEventListener(IOErrorEvent.IO_ERROR, onClipError);
    			trace("COULD NOT FIND CLIP TO LOAD!!!");
    		}
    		
    		
    	}
    }
    And then in the swfs I use this code to tell it to load and unload swfs.

    Code:
    function goHome(event:MouseEvent):void{ goTo("home.swf"); }
    
    function goTo(url:String):void {
    	MovingAheadMain(parent.parent).loadClip(url);
    }
    I tried putting your code in here, but I must be putting it in the wrong places and putting it in incorrectly. Where do I put it/can I still add it? Sorry I'm so hopeless..

  4. #4
    Total Universe Mod jAQUAN's Avatar
    Join Date
    Jul 2000
    Location
    Honolulu
    Posts
    2,429
    MovingAheadMain should be where you store 100% of your navigation logic. Having a child movie send direct commands to a parent movie is bad form and a pain in the ass to make widespread changes.

    1. In MovingAheadMain, declare the state variables I mentioned.
    2. Have the loaded .swfs do nothing more than broadcast an event. (I recommend creating a custom event class so that you can send customized data with it).
    3. Have MovingAheadMain add event listeners for your custom event to your loaded .swf's who handlers will read the data from the event object and set the state variables accordingly. Then have that same handler call your loadClip() which will in turn call onClipLoaded where you should have some conditional logic to determine wether or not the loaded .swf needs to have its playhead controlled.

    Centralizing the logic like this "decouples" the connection between the parent and child movies making edits much easier. Further, all child movies can extend a base class that defines the basic event dispatching so if that needs to change, you only have to change it in one place.

    Here is a decent example of creating custom events. It's really not that hard once you do it once or twice. http://evolve.reintroducing.com/2007...custom-events/

    Briefly, here's how your listener/broadcaster set up might look.

    Code:
    //in any child movie's document class
    package{
      import flash.events.*;
      import MyCustomEvent;
      public function MyChildMovie(){
        someButton.addEventListener(MouseEvent.CLICK, onClick);
      }
    
      public function onClick(event:MouseEvent):void{
        dispatchEvent(new MyCustomEvent(MyCustomEvent.CUSTOM_EVENT, /* parametes you defined in MyCustomEvent.as */));
      }
    }
    Code:
    in MovingAheadMain's onCustomEvent() method
    public function onCustomEvent(event:MyCustomEvent):void{
      //if for instance you declared a property in your custom event class
      //called activityThatIsBroadcasting, you would read it like
      if(event.activityThatIsBroadcasting == "activity2"){
        lastActivity = "activity2";
        loadClip("home.swf");
      }
      
    }
    
    //and then onClipLoaded can check the value of lastActivity and react accordingly.public function onClipLoaded(e:Event):void {
    	_loader.removeEventListener(Event.COMPLETE, onClipLoaded);
    	_loader.removeEventListener(IOErrorEvent.IO_ERROR, onClipError);
    			
    			
    	addChild(_loader);
    			
    			
    	_isLoaded = true;
            _loader.contentLoaderInfo.content.addEventListener(MyCustomEvent.CUSTOM_EVENT, onCustomEvent);
           if(lastActivity == "activity2"){
               _loader.contentLoaderInfo.content.gotoAndPlay(50);
           }
    }
    Last edited by jAQUAN; 11-11-2009 at 11:21 AM.

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