Go to specific frame after external swf has been loaded AS3 - actionscript-3

I have been looking for solutions around here but I can't seem to get it right.
Basically I am trying to load an external swf after clicking on a 'Next' button and it will automatically go to a specific frame eg. frame 8 instead of frame 1.
At first I've got an error of using of using MovieClip function in a Loader and such.
Here's my code
nextBtn.addEventListener(MouseEvent.CLICK, fl_ClickToLoadUnloadSWF_1);
var fl_Loader1:Loader;
var fl_ToLoad1:Boolean = true;
function fl_ClickToLoadUnloadSWF_1(event:MouseEvent):void
{
if(fl_ToLoad1)
{
fl_Loader1 = new Loader();
fl_Loader1.load(new URLRequest("projectnowd.swf"));
addChild(fl_Loader1);
var fl_Loader1:MovieClip = event.target.content as MovieClip;
fl_Loader1.gotoAndStop(8);
}
else
{
fl_Loader1.unload();
removeChild(fl_Loader1);
fl_Loader1 = null;
}
fl_ToLoad1 = !fl_ToLoad1;
}

You can access content of loaded swf only after event. Complete was dispatched while loading swf file on to the stage.
Define event handler method to start from 8 th frame
function loaderCompleteHandler(evt:Event):void {
var loadedMovie:MovieClipp = evt.currentTarget.content as MovieClip;
loadedMovie.gotoAndStop(8);
}
Replace if block with below lines of code
if(fl_ToLoad1)
{
fl_Loader1 = new Loader();
fl_Loader1.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
fl_Loader1.load(new URLRequest("projectnowd.swf"));
addChild(fl_Loader1);
}
Happy coding :)

Related

Unloading swf file through button click

So I'd like to set this up to where you click on a button it loads a new scene and unloads the previous scene.
This is what I have so far.
staart.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
function loadSWF(swfURL){
var myLoader:Loader = new Loader();
var mySWF:URLRequest = new URLRequest(swfURL);
myLoader.contentLoaderInfo.addEventListener
(Event.COMPLETE,onCompleteHandler);
myLoader.contentLoaderInfo.addEventListener
(ProgressEvent.PROGRESS,onProgressHandler);
myLoader.load(mySWF);
}
function onCompleteHandler(loadEvent:Event){
addChild(loadEvent.currentTarget.content);
loadEvent.currentTarget.content.gotoAndStop(swfFrame);
}
function onProgressHandler(myProgress:ProgressEvent){
var percent:Number =
Math.round(myProgress.bytesLoaded/myProgress.bytesTotal*100);
trace(percent+"% loaded");
}
}
var swfFrame:Number= 1;
loadSWF("home.swf");
}
Is it possible to unload a specific swf file or previous swf file through a newly loaded swf file?
You should create a variable for your swf.
Add this to your code :
var mc:MovieClip = new MovieClip();
// Adds the movie clip at initialization.
addChild(mc);
and modify your onCompleteHandler method like this :
function onCompleteHandler(loadEvent:Event){
// Changes the content of your movie clip.
mc = loadEvent.currentTarget.content;
mc.gotoAndStop(swfFrame);
}
shawn gave you the right answer but there are 2 other problems in your code:
There's a typo in element staart and a potential memory leak because you add event listeners without removing them. You should add the following two lines in onCompleteListener function:
loadEvent.currentTarget.removeEventListeners(Event.COMPLETE,onCompleteHandler)
loadEvent.currentTarget.removeEventListeners(ProgressEvent.PROGRESS,onProgressHandler)
If you don't remove the listeners, the garbage collector will be unable to free the memory of every loader you create on each click

How to loop SWF file loaded with Loader?

I want to loop a swf file that has been loaded with via the Loader class in AS3.
My code looks as following:
public class MyLoader extends MovieClip {
public function MyLoader() {
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("external-movie.swf");
myLoader.load(url);
myLoader.contentLoaderInfo.addEventListener("complete", function() {
});
addChild(myLoader);
}
}
From what I understand the Loader has no event for when the embedded movie is finished? Is there a way to figure that out? It must not be a AS3 implementation. I just want a movie that has been exported from Indesign to run in a loop. Thanks in advance
Especially when you have little experience programming you should avoid dirty shortcuts as they'll only get you a lot of trouble. So avoid anonymous function and avoid using string in place of static event variables.
This being said, if your loaded movie has its own timeline then it will be converted into a MovieClip. Also that movie is not embedded but loaded and that's a big difference.
Keep a reference of that movie and the loader:
private var theLoadedMovie:MovieClip;
private var myLoader:Loader;
Listen for the INIT event instead of the COMPLETE event (movies with timeline start to play when their first frame is loaded "INIT", the COMPLETE event fires when the whole movie is loaded).
myLoader = new Loader();
var url:URLRequest = new URLRequest("external-movie.swf");
myLoader.load(url);
myLoader.contentLoaderInfo.addEventListener(Event.INIT, handleInit);
In your handleInit method keep a reference of that movie:
theLoadedMovie = myLoader.content as MovieClip;
addChild(theLoadedMovie);
theLoadedMovie.addEventListener(Event.ENTERFRAME, handleEnterFrame);
in your handleEnterFrame method check the movie progress to know when it has ended:
if(theLoadedMovie.currentFrame == theLoadedMovie.totalFrames)
{
//movie has reached then end
}

Loading another swf file using AS3

I'm trying to load in another swf on a button click using Aaction Script 3.
The problem I'm having is that it just seems to load and mix the movies together. Is is possible to load and replace on stage the newly loaded swf similar to how you could do this in AS2 using loadMovieNum()
This is what I have so far:
//Add event listener for button click
backButton.addEventListener(MouseEvent.CLICK, backButtonClick);
//Create a function for the button click
function backButtonClick(ev:MouseEvent):void
{
var request:URLRequest = new URLRequest("2.swf");
var loader:Loader = new Loader()
loader.load(request);
addChild(loader);
}
Many thanks
Use the loader like this:
//Add event listener for button click
var singleLoader:Loader = new Loader();
backButton.addEventListener(MouseEvent.CLICK, backButtonClick);
//Create a function for the button click
function backButtonClick(ev:MouseEvent):void
{
var request:URLRequest = new URLRequest("2.swf");
singleLoader.load(request);
addChild(loader);
}
What you're doing is you're creating a new Loader every single time for every new SWF you're loading. Just use a single loader and each time you load content on it, it should replace the existing content. If not, adjust the code like so:
function backButtonClick(ev:MouseEvent):void
{
var request:URLRequest = new URLRequest("2.swf");
singleLoader.unloadAndStop(true);
singleLoader.load(request);
addChild(loader);
}
See the documentation for more: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Loader.html
Update
If you want to clear everything off the stage when you do this, see the following question & answer My Actionscript 3.0 Stage will not clear.

AS3 externally loaded swf to control stage and MovieClips and their children?

I have 2 swf files. One is loaded and loading an externally loaded swf into it.
Here is the code in the first loaded swf: #1
var logo:Loader = new Loader();
logo.load(new URLRequest("images/Logo.png"));
logo.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadLogo);
function LoadLogo(e:Event):void
{
addChild(logo);
}
/// The SWF I AM LOADING
var Beau:Loader = new Loader();
Beau.load(new URLRequest("Beau.swf"));
Beau.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadBeau);
function LoadBeau(e:Event)
{
addChild(Beau);
}
NOW HERE IS THE CODE FOR THE BEAU SWF LOADED: #2
import flash.display.MovieClip;
bird.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
//// I WANT TO BE ABLE TO ADD CODE TO CONTROL MOVIECLIPS
//// AND CHILDREN form this externally loaded swf. How do
//// I do that? Below code does not work.
var logo:MovieClip;
var ControlLogo:MovieClip = MovieClip(logo.content);
ControlLogo.alpha = .3;
}
EDIT
ok your code and tutorials are great. I am having major SANDBOX issues now when I make the clip load from an external URL. I am also coding for an ANDROID using FLASH CS5.5. Its not allowing me to use Security.allowDomain("*");
BOTTOME LINE IS THE NEWLY LOADED SWF can not access the PARENT WITHOUT PERMISSION BUT I DON'T KNOW HOW TO GIVE IT PERMISSION.... using the AIR/ANDROID PLAYER.
use property parent
parent gives loader
parent.parent gives swf#1
So you can write function as given below
function fl_MouseClickHandler(event:MouseEvent):void
{
var swf1:Object = parent.parent;
var logo:Loader = swf1.logo;
var ControlLogo:Bitmap = Bitmap(logo.content); // because logo loads an image
ControlLogo.alpha = .3;
}
make sure that logo is not a local variable, but global and public in swf#1
public var logo:Loader = new Loader();
EDIT:
logo:Loader gets added to SWF#1. Loads image, so content is Bitmap.
beau:Loader gets added to stage. Loads swf (SWF#2), so content is MovieClip.
so now
root is SWF#1
parent of beau is SWF#1
parent of SWF#2 is beau and parent of beau is SWF#1
so for SWF#2, SWF#1 is parent of parent so parent.parent
If you are not creating public variables, you can manage this by using property name.
var logo:Loader = new Loader();
logo.name = "logo";
...
...
var beau:Loader = new Loader();
beau.name = "beau";
...
...
Then anywhere in swf#2
var swf1:Object = parent.parent;
var logo:Loader = Loader(swf1.getChildByName("logo"));
....
....
For accessing the content it is recommended to use type casting as I have shown
var ControlLogo:Bitmap = Bitmap(logo.content); // because logo loads an image
so that you can check as shown below and avoid runtime errors
var ControlLogo:Bitmap = Bitmap(logo.content);
if(ControlLogo){
}
If you want to so something irrespective of content do as shown below
var ControlLogo:Object = logo.content;
if(ControlLogo && ControlLogo.hasOwnProperty("alpha")){
ControlLogo.alpha = 0.4;
}

Why do MovieClipLoader events not fire when loaded into an AS3 wrapper?

While trying to answer this question: Call to an AS2 function from the AS3 container I have come across a roadblock. The setup is an AS3 SWF which loads an AS2 SWF, which in turn loads another AS2 SWF. Communication between the AS3 SWF and the parent AS2 SWF is achieved through localConnection.
child_as2.swf - This is a very simple timeline animation of a box moving across the screen with the following code on frame 1:
stop();
function playMovie() {
play();
}
parent_as2.swf - This is the intermediary AS2 container which loads in child_as2.swf. The load is triggered by a LocalConnection call:
import mx.utils.Delegate;
this._lockroot = true;
var container:MovieClip = createEmptyMovieClip("container", 10);
//mustn't cast this or the Delegate breaks
var mcLoader = new MovieClipLoader();
mcLoader._lockroot = true;
mcLoader.onLoadInit = Delegate.create(this,onMCLoadInit);
function onMCLoadInit() {
trace("load init");
container.playMovie();
}
//LocalConnection code
var myLC:LocalConnection = new LocalConnection();
myLC.loadChild = function(){
mcLoader.loadClip("child_as2.swf", container);
trace("loading");
}
myLC.connect("AVM");
parent_as3.swf - This is the outer wrapper, written in AS3. It loads parent_as2.swf, and communicates with it via LocalConnection:
var myLC:LocalConnection = new LocalConnection();
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT,onLoaded);
loader.load(new URLRequest("parent_as2.swf"));
addChild(loader);
function onLoaded(event:Event):void {
//setTimeout hack to circumvent #2000 Security context error
setTimeout(function() {
myLC.send("AVM", "loadChild");
},1);
}
The issue is that the onMCLoadInit function in parent_as2 is never called when it is loaded inside the AS3 wrapper, although the load does take place. The events also fail when using a listener object in place of Delegate. The box from child_as2.swf is visible, but never starts moving. However, if I run parent_as2.swf on it's own and start the load without the LocalConnection it works fine. It also wroks correctly when triggered from an external LocalConnection call. Why does the AS3 wrapper prevent the MovieClipLoader's events from firing?
Update:
So accepting that no events can be fired from the MovieClipLoader in parent_as2.swf, I have modified the code to detect the loadInit state by a combination of polling MovieClipLoader.getProgress() and the existance of a function in child_as2.swf. It's not pretty but it seems to work. I would still much rather be able to offer a solution using events though.
var container:MovieClip = createEmptyMovieClip("container", 10);
var mcLoader:MovieClipLoader = new MovieClipLoader();
var loadStarted:Boolean;
var checkingInt:Number;
function checkProgress() {
var progObj:Object = mcLoader.getProgress(container);
if(progObj.bytesLoaded == progObj.bytesTotal && loadStarted) {
//load complete, wait for loadInit
if(typeof(container.playMovie) == "function") {
//loadInit
clearInterval(checkingInt);
container.playMovie();
}
}
//ensures the first loop is ignored due to inaccuracy with reporting
loadStarted = true;
}
//LocalConnection code
var myLC:LocalConnection = new LocalConnection();
myLC.loadChild = function() {
loadStarted = false;
mcLoader.loadClip("child_as2.swf", container);
checkingInt = setInterval(checkProgress,5);
}
myLC.connect("AVM");
I think its the delegate scope in as2 when loaded into a parent the parent becomes _root.
So "this" would be referring to the parent root where the function does not exist.
Have you tried putting this._lockroot = true; in parent_as2?
Here is a better explanation
Also as a side note to your security hack.
The proper fix for that would be to have the child contact the parent and issue an "I am ready type command" which would start the communication events from parent to child.
setTimeout is just delaying any calls to the child giving it time to initialize which could be bad on slower computers.
I did alot of loading AS2 into AS3 a few years ago. If you can't tell lol