How to apply removeChild to multiple swf's - actionscript-3

I have a project in which the user has the option of pressing any one of 5 keyboard keys that each loads a different .swf file. I would like whatever key the user presses to unload whatever swf is currently playing and load whichever one is associated with the key pressed.
I have no problem coding this with two .swf's --each one loads and simultaneously unloads the other-- however when I add a third, it becomes erratic and the third removeChild function does not work properly.
It would seem that the problem is that only one removeChild can be applied at a time. Is there a way around this?
The code I am using is on a frame within the main timeline and it is not associated with a container other than the stage onto which the the swf's are directly loaded:
var myLoader:Loader = new Loader();
var myRequest:URLRequest=new URLRequest("swf/darker.swf");
var Loader2:Loader = new Loader();
var Request2:URLRequest=new URLRequest("swf/animalinside.swf");
var Loader3:Loader = new Loader();
var Request3:URLRequest=new URLRequest("swf/berlin1.swf");
stage.addEventListener(KeyboardEvent.KEY_DOWN, Darker);
function Darker(e:KeyboardEvent):void {
if (e.charCode == 51) { //51=3
myLoader.load(myRequest);
addChild(myLoader);
removeChild(Loader2);
removeChild(Loader3);
}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, animalInside);
function animalInside(e:KeyboardEvent):void {
if (e.charCode == 52) { //52=4
Loader2.load(Request2);
addChild(Loader2);
removeChild(myLoader);
removeChild(Loader3);
}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, Berlin1);
function Berlin1(e:KeyboardEvent):void {
if (e.charCode == 53) { //53=5
Loader3.load(Request3);
addChild(Loader3);
removeChild(myLoader);
removeChild(Loader2);
}
}
I have tried adding multiple instances within the removeChild() parens like this:
removeChild(Loader3, Loader2, Loader4, ...); however it doesn't work.
Stacking the removeChild also doesn't seem to work:
removeChild(myLoader);
removeChild(Loader2);
removeChild(Loader3);
//etc.
Not sure how to proceed, any help would be much appreciated!
Thanks in advance,
Llyfre

I'd go about this a different route. A much easier route in fact. Take a look at the code I wrote below. I haven't tested it, but I am pretty sure this will work
var swfs:Array = ["swf/darker.swf","swf/animalinside.swf","swf/berlin1.swf"];
var swfHolder:Sprite = new Sprite();
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
function keyDownHandler(e:KeyboardEvent):void
{
//remove any previous children in swfHolder
while (swfHolder.numChildren > 0) swfHolder.removeChildAt(0);
//-- new loader and load the swf
var loader = new Loader();
switch (e.charCode)
{
case 51:
loader.load(new URLRequest(swfs[0]));
break;
case 52:
loader.load(new URLRequest(swfs[1]));
break;
case 53:
loader.load(new URLRequest(swfs[2]));
break;
}
swfHolder.addChild(loader);
}
addChild(swfHolder);

Related

Go to specific frame after external swf has been loaded AS3

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 :)

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

Flash AS3 load and replace movie

I have a loader mc...an animation that loops - when you click a button I want a new movie to load on top and replace the loader mc
Here is my current code:
btn_load.addEventListener(MouseEvent.CLICK, btn_load_press);
function btn_load_press(e:MouseEvent)
{
var reloadRequest:URLRequest = new URLRequest("new-movie.swf");
var loader:Loader = new Loader();
loader.load(reloadRequest);
addChild(loader);
}
But this puts it on top on my loader...effectively meaning the loader is still running in the background.
This is really simple in AS2 - and I'm not sure if it's even possible in AS3
To do this we'll need to add a listener for your loader.contentLoaderInfos complete event, then remove your animation once everything has finished loading.
btn_load.addEventListener(MouseEvent.CLICK, btn_load_press);
function btn_load_press(e:MouseEvent)
{
var reloadRequest:URLRequest = new URLRequest("new-movie.swf");
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loader_complete);
loader.load(reloadRequest);
addChild(loader);
}
function loader_complete(e:Event)
{
e.target.removeEventListener(Event.COMPLETE,loader_complete);
removeChild(loader_mc);
}

Some problems regarding removing a child added dynamically

I have this function where I want to get a movie clip (the function target) and change it to another one. The problem is that it obviously removes the movie clip before the new one is loaded.
var changePeca:Loader = new Loader;
var changeLoad:URLRequest = new URLRequest(e.target.name.substr(0,4)+".png");
changePeca.load(changeLoad);
e.target.removeChildAt(0);
e.target.addChild(changePeca);
I know that I must use the Event.COMPLETE thing, but how do I say which movie clip to remove, since I cant use e.target anymore?
"The problem is that it obviously removes the movie clip before the new
one is loaded."
Because you code says do so! :) You need to add the event listener which checks if the stuff is loaded.
private var holderMC:Sprite;
private var imageLoader:Loader;
private function load(e:Event):void
{
holderMC = e.target as Sprite // or something else you have there, just store it.
imageLoader = new Loader ();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoadComplete)
imageLoader.load(new URLRequest(e.target.name.substr(0, 4) + ".png"));
}
private function handleLoadComplete(e:Event):void
{
if(holderMC.numChildren > 0)
holderMC.removeChildAt(0);
holderMC.addChild(imageLoader.content)
}

Controlling FPS of a loaded swf

I'm working on a flash app where I load multiple swf's. But the problem is that they have different framerates (12/25/30). If I add 2 swf's they both play at 25fps. I found numerous topic about this but I can't get it to work (in AS3). Does anyone know why it doesn't work and how to make it working?
public class MainClass extends MovieClip
{
var loader:Loader = new Loader();
var request:URLRequest;
var mcMedia:MovieClip = new MovieClip();
MovieClip.prototype.setFrameRate = function(frameRate:Number)
{
var mc:MovieClip = this;
if (mc.tweenFaster != null)
{
Timer(mc.tweenFaster).stop();
}
mc.tweenFaster = new Timer(1000/frameRate);
mc.tweenFaster.addEventListener(TimerEvent.TIMER, timelineFaster);
mc.tweenFaster.start();
function timelineFaster(event:TimerEvent = null)
{
if (mc.currentFrame == mc.totalFrames)
{
mc.tweenFaster.stop();
mc.gotoAndStop(1);
}
else
{
trace(mc.currentFrame);
mc.nextFrame();
}
event.updateAfterEvent();
}
}
public function MainClass()
{
configureListeners();
request = new URLRequest("data/7/7.swf");
try
{
loader.load(request);
}
catch (error:Error)
{
trace("Unable to load requested document.");
}
}
private function configureListeners():void
{
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.contentLoaderInfo.addEventListener(Event.OPEN, openHandler);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
loader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}
private function completeHandler(event:Event):void
{
loader.content.scaleX = 550/event.target.width;
loader.content.scaleY = 400/event.target.height;
mcMedia.addChild(loader);
mcMedia.setFrameRate(12);
addChild(mcMedia);
}
In as3, if you're just looking to change the framerate, use stage.frameRate = 12; or whatever;
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Stage.html#frameRate
In AS3, while you can use prototypes, you generally don't. I'd rewrite your setFrameRate function (which is badly named, shouldn't it be more.. tweenFaster, or matchFrameRate or something?)
I'd make a helper function like this:
package util{
//imports
public class TweenFasterMC extends MovieClip{
public var mc:MovieClip;
public function matchFrameRate(frameRate:Number):void
{
if (tweenFaster != null)
{
Timer(mc.tweenFaster).stop();
}
tweenFaster = new Timer(1000/frameRate);
tweenFaster.addEventListener(TimerEvent.TIMER, timelineFaster);
tweenFaster.start();
}
function timelineFaster(event:TimerEvent = null):void
{
if (currentFrame == totalFrames)
{
tweenFaster.stop();
gotoAndStop(1);
}
else
{
trace(currentFrame);
nextFrame();
}
event.updateAfterEvent();
}
}
Also, clean up your event listeners, that strong timer event listener will cause a lot of problems if you have a lot of mc's your applying this functionality to.
As far as I know all MovieClips in one flash player instance (sharing the same 'stage') will run at the same speed - there is no way to have two clips running at different speeds. So to adjust the speed you have to resort to calling gotoAndStop() on all MovieClips in the loaded clip at the right time - that won't be fun.
Code along the lines that quoo is showing will only work if the loaded swf contains just 1 MovieClip (no nesting) as far as I can see.
It seems to me that the most likely reason why this wouldn't work is that it requires every clip you load to be a simple, completely non-dynamic animation that loops for ever. If the loaded content is that simple, why not just adjust it to look better at 30fps? (If it's extremely long, a JSFL script could automate the process of adding extra frames.) Alternately, if the content isn't that simple, then attempting to change its timing by calling nextFrame from elsewhere is not going to give you what you want.
With all that said, if you're sure this is what you want to do but you're getting 0 as a return for currentFrame in your loaded content, are you sure they are AS3 SWFs? If they aren't, AS3/AS2 interoperation is a hairy subject that will warrant reading up on.
This is a real hassle, I've been scouring the net for an answer. I have particles following a path, and I want to change the speed that these particles follow the path dynamically, without changing the whole movie. just the particles movie clip.
I've tried greensock, but, that doesn't really work like i need.. i'd think there would be something that you can change dynamically for each mc, but, no dice.
the stage.frameset is only for the whole movie... argggggggg..... sucks..