Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
X10

How to load 2 SWF's then play one after the other on repeat?

Recommended Posts

Hi All,

This is my first time using LoaderMax so I thought I'd try something simple, but even after reading the documentation and several posts on the forum I'm having trouble.

 

What I'd like to do is load 2 SWF's (that have been built with AS3 and TimelineMax) and play the first one, then when it completes, play the second one, then when that completes loop through back to the 1st and repeat.

 

The code below gets the swfs fine, but they play as soon as they're loaded, and I know 'autoPlay:false' only deals with the playhead, so doesn't work for TimelineMax based animations. I also read up a little on rawcontent, but I'm still missing something key here.

 

I also had a look at this (viewtopic.php?f=6&t=4673) but I think it just confused me more, any help would really be appreciated!

 

X10

 

import com.greensock.*;
import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.display.*;

//create a LoaderMax named "mainQueue" and set up onProgress, onComplete and onError listeners
var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler, onComplete:completeHandler, onError:errorHandler});

//append several loaders
queue.append( new SWFLoader("Clip1.swf", {name:"childClip1", estimatedBytes:200000, container:this, /*x:250,*/ autoPlay:false}) );
queue.append( new SWFLoader("Clip2.swf", {name:"childClip2", estimatedBytes:200000, container:this, /*x:250,*/ autoPlay:false}) );

//prioritize the loader named "childClip1"
LoaderMax.prioritize("childClip1");

//start loading
queue.load();

function progressHandler(event:LoaderEvent):void {
   trace("progress: " + event.target.progress);
}

function completeHandler(event:LoaderEvent):void {
var SWF1:ContentDisplay = LoaderMax.getContent("childClip1").rawContent;
var SWF2:ContentDisplay = LoaderMax.getContent("childClip2").rawContent;
SWF2.rawContent.pause();
trace(event.target + " is complete!");
}

function errorHandler(event:LoaderEvent):void {
   trace("error occured with " + event.target + ": " + event.text);
}

Link to comment
Share on other sites

Hey X10,

 

Congrats on getting into LoaderMax. Unfortunately what you describe as simple is actually a bit complicated. I've never done this before so I don't have an exact code solution, but here is some theory:

 

when both swfs are fully loaded:

 

tell swf 1 to play its timeline

swf1's timeline must have an onComplete eventHandler that communicates to the parent swf that it is done playing.

 

the parent swf needs to have a function in it that will then communicate to swf2 that its timeline must play.

 

Technically, I imagine your swf1 could talk directly to swf2, but for some reason that sounds more troubling to me.

 

If I have time later today I'll try to get something like this work.

 

 

 

------

just realized i had some sample files laying around demonstrating how a parent can communicate with a child swf and vice versa.

 

PARENT FLA: functionFromSub.fla

 

import com.greensock.*;
import com.greensock.loading.*;
import com.greensock.easing.*;
import com.greensock.events.LoaderEvent;



var loader:SWFLoader;

//load an external swf
loader=new SWFLoader("ext.swf",{container:this.holder,x:0,y:0,alpha:0,name:"swf1",onComplete:completeHandler});

loader.load();


//when loading done, fade it in
function completeHandler(e:LoaderEvent):void {
TweenLite.to(e.target.content, 1, {alpha:1});
}


function onParentFiredFromLoaded(){
trace("the loaded clip called this function");
}


stage.addEventListener(MouseEvent.CLICK, testFunctionInSub);

function testFunctionInSub(e:Event){
//call a function FROM this Movie IN the LOADED movie
LoaderMax.getLoader("swf1").rawContent.calledFromMain();
}

 

this file loads a swf called ext.swf and fades it in when loaded.

clicking anywhere in the parent (functionFromSub.swf) will fire a function in the loaded swf (ext.swf)

 

EXTERNAL SWF: ext.swf

 

trace("subSwf is here");

btn.addEventListener(MouseEvent.CLICK, test);


//this function calls a function in parent: functionFromSub.swf
function test(e:Event){
trace("fired from btn");
trace(this.parent.parent as MovieClip);

//YOUR PATH MAY HAVE TO CHANGE THE NUMBER OF PARENTS... NOT SURE.

var parentMovie:MovieClip = this.parent.parent.parent as MovieClip;
parentMovie.onParentFiredFromLoaded();


}

//this function gets called FROM parent: functionFromSub.swf
function calledFromMain():void{
trace("calledFromMain");
}

 

this swf can communicate TO the swf it was loaded INTO and also has a function that can be triggered FROM its parent.

click on this red swf to see its parent fire a trace from onParentFiredFromLoaded();

 

These files only really trace messages, but should be a good starting point for ParentSwf > ChildSwf communication.

 

see attached

 

Carl

Link to comment
Share on other sites

  • 4 months later...

If you wanted to get the swf to play when you call

calledFromMain() from the main swf, how do you do that?

 

i.e.:

rollGO = new TimelineMax({paused:true, onComplete:rollDone}); yada yada...

 

function calledFromMain():void{

rollGO.play();

trace("calledFromMain");

}

 

This of course doesn't work. No matter what I do (i.e. making rollGO public, etc.)

I can't get rollGO to be recognized as anything but null within calledFromMain() function.

 

I need for the main swf to tell the sub-swf to play itself. Can't figure it out. Help.

 

Thanks -

Vic

Link to comment
Share on other sites

Im kind of running into the same issue - I need to see if the current swf that is playing is done. I solved it by putting a listener on the current playing swf and check for the last frame.

 

What I mean is say _currentSwf has the rawContent :

_currentSwf = _swfLoader.rawContent;

 

Then put a listener on that current swf to check where it is :

 
_currentSWF.addEventListener(Event.ENTER_FRAME , checkIfComplete);

private function checkIfComplete(e:Event):void 
{	
//if it the current frame of the swf equals the last frame
if (_currentSwf.currentFrame == _currentSwf.totalFrames) 
{
	 trace("Im at the end");    
              // lets remove the listener since we dont need it any more. 
	_currentSwf.removeEventListener(Event.ENTER_FRAME, checkLastFrame);
}
}    

 

Anyone see any issues w/ doing it that way?

Link to comment
Share on other sites

  • 3 months later...

I'm going to chime here with a possible solution in case someone else has a similar issue.

I do this with segmented MovieClip animations, so I would expect the same technique to work with loaded swf file animations.

This basically loads all of the swf files up front and pushes them into an Array, then starts a looping sequence of the swf files from the Array.

Setup the XML file with the swfloaders:

<?xml version="1.0" encoding="UTF-8"?>



	load="true" 
	name="blue"	
	url="blue.swf"/>



	load="true" 
	name="green"
	url="green.swf"/>



	load="true" 
	name="red"
	url="red.swf"/>



Load the swf files with XMLLoader, push them into an array, then start the loop.

import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.display.*;
import flash.display.MovieClip;

LoaderMax.activate([sWFLoader]);

var sprite:Sprite;
var selector:int;
var swfArray:Array = new Array();
var len:int;
var xml:XML;

var xmlLoader:XMLLoader = new XMLLoader("data/nav.xml",{name:"xmlData",maxConnections:1,onComplete:initApp,onChildComplete:pushToArray});
xmlLoader.load();

function pushToArray(e:LoaderEvent):void
{
var swf:MovieClip = e.target.rawContent as MovieClip;
swfArray.push(swf);
}

function initApp(e:LoaderEvent):void
{
sprite = new Sprite();
selector = 0;
len = swfArray.length-1;

sprite.addChild(swfArray[selector]);
addChild(sprite);
addEventListener("next swf", loadNext);
}

function loadNext(e:Event):void
{
if (selector < len)
{
	selector++;
}
else
{
	selector = 0;
}

trace("selector:" + selector);

while (sprite.numChildren > 0)
{
	sprite.removeChildAt(0);
}

var _swf:MovieClip = MovieClip(swfArray[selector]);
_swf.gotoAndPlay(1);
sprite.addChild(swfArray[selector]);
}

 

At the end of the timeline of each swf file, stop the timeline and dispatch an event.

The main timeline is listening for this event, which will trigger the removal of the old swf, and addition of the next swf in the Array.

stop();
dispatchEvent(new Event("next swf", true));

Link to comment
Share on other sites

Hey Snick,

 

Thanks so much for contributing to this topic. I'm sure that technique could come in handy for people. the dispatchEvent technique would really shine if some sort of user action in the loaded swf needed to trigger the playback of the next swf in the sequence.

 

Rob_v, I like your approach too with checking the currentFrame and I don't see anything wrong with it.

 

I did a similar combination of loading multiple swfs and waiting for the currentFrame to = totalFrames but without XMLLoader (as used by Snick)

 

so to add another solution to the mix, grab the files from the bottom of this page:

 

http://www.snorkl.tv/2011/11/snorklreport-big-news/ - load multiple swfs and play in sequence with no code in the child swfs

 

another solution would be to take Snick's XMLLoader and combine it with the currentFrame check that rob and I use. plenty of options!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×