I have a code that loads 4 swf files into main swf file one after another , but unfortunately I faced 2 problems : here is my code :
import com.greensock.*;
import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
progress_mc.scaleX = 0;
var loaderIndex:Number = -1;
var currentLoader:SWFLoader;
var swfs:LoaderMax = new
LoaderMax({onComplete:completeHandler,onProgress:progressHandler,onChildComplete:childCompleteHandler});
swfs.append(new SWFLoader("part1.swf", {container:container_mc, autoPlay:false}));
swfs.append(new SWFLoader("part2.swf", {container:container_mc, autoPlay:false}));
swfs.append(new SWFLoader("part3.swf", {container:container_mc, autoPlay:false}));
swfs.append(new SWFLoader("part4.swf", {container:container_mc, autoPlay:false}));
function progressHandler(e:LoaderEvent):void {
progress_mc.scaleX = e.target.progress;
}
function childCompleteHandler(e:LoaderEvent):void {
trace(e.target + " loaded");
e.target.content.visible = false;
}
function completeHandler(e:LoaderEvent):void {
trace("all swfs loaded");
progress_mc.visible = false;
initCurrentLoader();
addEventListener(Event.ENTER_FRAME, trackSWFPlayback);
}
function initCurrentLoader() {
loaderIndex++;
if (loaderIndex == swfs.numChildren) {
//reset back to 0 if the last swf has already played
loaderIndex = 0;
}
//dynamically reference current loader based on value of loaderIndex
currentLoader = swfs.getChildAt(loaderIndex);
//make the content of the current loader visible
currentLoader.content.visible = true;
//tell the current loader's swf to to play
currentLoader.rawContent.gotoAndPlay(1);
}
function trackSWFPlayback(e:Event):void {
//trace(currentLoader.rawContent.currentFrame);
//detect if the loaded swf is on the last frame
if (currentLoader.rawContent.currentFrame == currentLoader.rawContent.totalFrames) {
trace("swf done");
//hide and stop current swf
currentLoader.content.visible = false;
currentLoader.rawContent.stop();
//set up and play the next swf
initCurrentLoader();
}
}
load_btn.addEventListener(MouseEvent.CLICK, loadSWFs)
function loadSWFs(e:MouseEvent):void{
load_btn.visible = false;
swfs.load();
}
problem 1 : part1.swf that is a swf file not made with adobe flash does't load. here is the error I can see each time :
RangeError: Error #2006: The supplied index is out of bounds.
at flash.display::DisplayObjectContainer/getChildAt()
at dblogo()
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()
at flash.display::MovieClip()
at dbmovie()
SWFLoader 'loader2' (part2.swf) loaded
SWFLoader 'loader1' (part1.swf) loaded
SWFLoader 'loader4' (part4.swf) loaded
SWFLoader 'loader3' (part3.swf) loaded
all swfs loaded
swf done
poblem 2 : I have a line in my script that stops last swf . as I want to load swf files that maybe huge I rather that to unload instead of just stoping swfs . how to unload each swf instead of stoping it .
as I'm completely new to flash and as3 can every one simply edit my as3 to fix these two main problems .
Any Any Any Suggestions are EXTREMELY appreciated...Thanks a lot
I believe this check is wrong - if you would only have one swf the numChildren would be 1 but its index would be 0.
Start with the index 0 instead of -1:
var loaderIndex:Number = 0;
And then:
if (loaderIndex == swfs.numChildren - 1) // index 0 equals numchildren = 1
{
//reset back to 0 if the last swf has already played
// Why do you reset the index if you only want to play the swfs once ? You should just stop here and remove your enterframe event listener
loaderIndex = 0;
}
loaderIndex++;
As for unloading there is a way to remove the loader with swfs.remove(loaderInstance) but you would need to keep the instances of your loaders. In this case you would not need to increase your loaderIndex but always keep it at 0. Another way is swfs.dispose() which will get rid of ALL content in your LoaderMax (in this case you can only do this after the last swf have played)
Related
I'm an as3 newbie, i have one button as name tombol fuctioning to Loading External swf & going to Specific Frame by clicking buttons, this works fine.
import flash.events.MouseEvent;
tombol.addEventListener(MouseEvent.CLICK, tekan2);
function tekan2 (e: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=2;
loadSWF("2.swf");
}
This file save as 1.swf and loading file 2.swf go to frame 2, but file 1.swf still loading, so this script loading 2 file swfs(file 2.swf frame 2 loading with file 1.swf appears). How to file 1.swf can unloading same time when I click the button, so just file 2.swf frame appears on stage.
Generally you can cancel a Loader's load operation by using the command close(). Before cancelling you need to make sure that the Loader actually loads data, otherwise an Error will be thrown:
if (myLoader.contentLoaderInfo.bytesLoaded > 0 &&
myLoader.contentLoaderInfo.bytesLoaded < myLoader.contentLoaderInfo.bytesTotal)
{
myLoader.cancel();
}
EDIT:
You can access the loader of 1.swf by root.loaderInfo.
In your function loadSWF you can add the following code to prevent 1.swf from loading further:
if (root.loaderInfo.loader && root.loaderInfo.bytesLoaded > 0 &&
root.loaderInfo.bytesLoaded < root.loaderInfo.bytesTotal)
{
root.loaderInfo.loader.cancel();
}
However, I'm not completely sure if you really can cancel the loading process of 1.swf (I have never tried out something like this). Architecture-wise, it would make sense to have a third SWF file, which is your Main SWF, and loads your other SWF files (1.swf and 2.swf, ...). In your main SWF you would need to define the Loader as class variable and not as a local variable as you are currently doing. Whenever you load a SWF, check if another loading operation is in progress and cancel it in that case. Ideally, you would place the button tombol in the Main SWF.
i really need some AS3 Script for run some function when i leave a specfic frame.
my reason is to put some function to stop video and resume my sound of mp3 player AFTER i exit the frame that contain FLV playback .
i use this script and it`s work great in FLash projector but stage.invalidate(); cause the Third party application maker like Swfkit and Zinc Not responding after i try to exit from flv playback frame.
Here is my Script :
stage.invalidate();
mene.addEventListener(Event.RENDER,exitingF);
mene.addEventListener(Event.REMOVED_FROM_STAGE, removedF);
function exitingF(e:Event):void{
controller.gotoAndStop(2);
pausePosition = sndChannel.position;
sndChannel.stop();
isPlaying = false;
}
function removedF(e:Event):void{
mene.stop();
controller.gotoAndStop(1);
sndChannel = soundClip.play(pausePosition);
isPlaying = true;
}
all i need is some another way to say flash run some script right after exit specfic frame ( go to another frame )
Try using the addFrameScript() function.
It works like so: OBJECT.addFrameScript(FRAME, CALLBACK)
This will add a script to a timeline and the callback will be executed whenever the specified frame is reached.
Here's an example I found: http://blog.newmovieclip.com/2007/04/30/add-a-frame-script-addframescript-dynamically-in-flash-cs3/
package com.newmovieclip{
import flash.display.MovieClip;
public class Main extends MovieClip {
public var myStar:Star;
//constructor
public function Main() {
//place a star on stage
myStar = new Star();
addChild(myStar);
//add script to star timeline on frame 5
myStar.addFrameScript(4,frameFunction); // (zero based)
}
private function frameFunction():void {
trace("Executing code for star Frame 5" );
//delete frame script by passing null as second parameter
myStar.addFrameScript(4,null);
}
}
}
Remember that frames are 0 based as mentioned in the inline comment from the example
I have a swf file loaded into a main movie. When the child is finished playing, ie reaches its final frame, I would like the swf to unload. Can anyone tell me what bits I can add to this code?
//start button
start_button_aboriginal.addEventListener(MouseEvent.CLICK, fl_ClickToLoadUnloadSWF_3,false,0,true);
import fl.display.ProLoader;
var fl_ProLoader_3:ProLoader;
var fl_ToLoad_3:Boolean = true;
function fl_ClickToLoadUnloadSWF_3(event:MouseEvent):void
{
//ADDED APR02 START
fl_ProLoader_3.contentLoaderInfo.addEventListener(Event.INIT, childInitHandler);
fl_ProLoader_3.load(new URLRequest("myths/myth_aboriginal.swf"));
//ADDED APR02 END
if(fl_ToLoad_3)
{
fl_ProLoader_3 = new ProLoader();
fl_ProLoader_3.load(new URLRequest("myths/myth_aboriginal.swf"));
addChild(fl_ProLoader_3);
fl_ProLoader_3.x = 114;
fl_ProLoader_3.y = 41;
}
else
{
removeChild(fl_ProLoader_3);
fl_ProLoader_3.unloadAndStop();
fl_ProLoader_3 = null;
}
// Toggle whether you want to load or unload the SWF
fl_ToLoad_3 = !fl_ToLoad_3;
}
You could
1) Use the undocumented addFrameScript function defined in the MovieClip class to place a callback on the last frame of the child SWF. Useful if you don't have control over the code in your loaded SWF.
addFrameScript() has the following signature:
addFrameScript(frameNumber, callback); //frameNumber is zero-based (unlike in the Flash authoring suite, here you would enter 0 to refer to the first frame, and 1 for the second.)
In the parent SWF, add the following:
function fl_ClickToLoadUnloadSWF_3(event:MouseEvent):void {
...
fl_ProLoader_3.contentLoaderInfo.addEventListener(Event.INIT, childInitHandler);
fl_ProLoader_3.load(new URLRequest("myths/myth_aboriginal.swf"));
...
}
function childInitHandler(event:Event):void {
MovieClip(fl_ProLoader_3.content).addFrameScript(MovieClip(fl_ProLoader_3.content).totalFrames-1, unloadChild);
}
function unloadChild() {
fl_ProLoader_3.unloadAndStop();
}
If you're worried about addFrameScript going away - don't be. When you put code on the timeline, all that code is actually compiled into functions in the document class, with frame listeners added via addFrameScript.
Remember to define function unloadChild().
function unloadChild():void {
fl_ProLoader_3.unloadAndStop();
}
-OR-
2) Dispatch an event from your loaded SWF when it reaches the final frame.
In last frame of child SWF:
this.dispatchEvent(new Event("lastFrameReached"));
In parent SWF, add the following:
fl_ProLoader_3.content.addEventListener("lastFrameReached", unloadChild);
-OR-
3) Subscribe to the ENTER_FRAME event of the child and check if the child is on its last frame.
In parent SWF, add the following:
fl_ProLoader_3.content.addEventListener(Event.ENTER_FRAME, checkIfEnded);
function checkIfEnded(event:Event):void {
if (fl_ProLoader_3.content.currentFrame == fl_ProLoader_3.content.totalFrames) {
unloadChild();
}
}
I personally prefer addFrameScript - seems to me a cleaner solution. Callback runs once, you don't have to poll and you don't need to modify the child SWF.
There are a number of ways to solve this, and it has been asked many times...
Unload child swf on last frame of child swf
When External SWF has reached Frame X, how do I unload it?
That said, one way you could resolve this without creating event listeners on the child swf, is by periodically checking the child swf for the current frame. If it's the last one on the swf, call the unload method.
// once every second, indefinitely.
var tick:Timer = new Timer(1000, 0);
tick.addEventListener(TimerEvent.TIMER, checkSWF);
tick.start();
//Load something to the stage.
var loader:Loader = new Loader();
loader.load(new URLRequest("child.swf"));
addChild(loader);
function checkSWF(e:Event):void {
if (loader.content.currentFrame == loader.content.totalFrames) {
tick.stop(); // stop the timer
loader.unloadAndStop();
}
}
I have loaded an external swf file which plays a flv file by default as swf is loaded. Now the problem is how do i remove the swf file from memory. my code :
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("ExternalSWF.swf");
myLoader.load(url);
detailMovieClip.movieHolder.addChild(myLoader);
I have tried many combinations of removeChild, unload and unloadAndStop but none works. I figure its all about not referencing correctly.
Update:
I went with the answer from Jegan, but it only work when i am testing in a dummy project which has only 1 numChildren, howver in real world code example numChildren reported 22 so i am not sure if that would be an issue. here is the real world code:
var myImageLoader:Loader;
var myImageRequest:URLRequest;
var theImagePath:String;
//part from xml processor function
theImagePath = "flash/"+myXML..item_video_link[n];
loadTheMovie(theImagePath);
function loadTheMovie(theImagePath):void{
myImageLoader = new Loader();
myImageRequest= new URLRequest(theImagePath);
myImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,showMeTheVideo);
myImageLoader.load(myImageRequest);
}
function showMeTheVideo(evt:Event):void{
detailsMovieClip_mc.details_video_holder.dynamicVideoHolder.addChild(myImageLoader);
}
stopVideo(sectionname):viod{
if(detailsMovieClip_mc.details_video_holder.dynamicVideoHolder.numChildren !=0){
trace("what is the number of children: "+numChildren);
myImageLoader.unloadAndStop();
detailsMovieClip_mc.details_video_holder.
dynamicVideoHolder.removeChild(myImageLoader);
}
}
stage.addEventListener(MouseEvent.CLICK, removeSWF);
function removeSWF (e:MouseEvent):void
{
if(detailMovieClip.movieHolder.numChildren !=0){
myLoader.unloadAndStop();
detailMovieClip.movieHolder.removeChild(myLoader);// empty the movieClip memory
}
}
OR
Name your Loader instance and then search by using getChildByName
myLoader.name = "myloader";
function removeSWF (e:MouseEvent):void
{
if(detailMovieClip.movieHolder.numChildren !=0){
Loader(detailMovieClip.movieHolder.getChildByName("myloader")).unloadAndStop();
detailMovieClip.movieHolder.removeChild(detailMovieClip.movieHolder.getChildByName("myloader"));// empty the movieClip memory
}
}
I guess this is because you are adding the loader to the scene itsef.
Either you want to keep this behavior, in this case there is a quick fix, remove the loader from the MovieClip by using removeChild(), then set the reference to null, or use the delete keyword.
Either you want to do it properly, in this case, listen for the LOADED event, adds the MovieClip contained by the loader.content to the target MovieClip. Then, when you want to unload it, remove the clip from the container using removeChild(), then loader.unload().
I need to have a swf load at the beginning, but I don't want to play about the last 3 seconds of the video.
Can someone help me out with a code that would basically have my swf play for "x" seconds?
Heres what I Have so far.. Currently it is set up to play the swf, but subtract "x" seconds from it but for some reason it doesn't seem to work
var mySwf:MovieClip;
var reducedTotalFrames:int;
var clipLoader:Loader = new Loader();
clipLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
clipLoader.load(new URLRequest("schoolintro.swf"));
function loadComplete(e:Event):void
{
mySwf = LoaderInfo(e.currentTarget).content as MovieClip;
var totalFrameCount:int = mySwf.currentScene.numFrames;
var secondsToSubtract:int = 3;
var threeSecondFrameCount:int = (stage.frameRate * secondsToSubtract);
reducedTotalFrames = totalFrameCount - threeSecondFrameCount;
stage.addEventListener(Event.ENTER_FRAME, onRender);
stage.addChild(mySwf);
}
function onRender(e:Event):void
{
if(mySwf != null && mySwf.currentFrame >= reducedTotalFrames){
//This is the end of the SWF with 3 seconds trimmed off. Here we can stop play
stage.removeEventListener(Event.ENTER_FRAME, onRender);
mySwf.stop();
//doSomethingElse();
}
}
Try some basic debugging, like placing trace statements in the code inside onRender to ensure it's being called, to ensure the mySwf reference is working correctly (for example, tracing out mySwf.currentScene.numFrames, and if its 0, you know you're not referencing your swf properly or the swf is not frame-based). If it the SWF is not frame-based, then you're going to have real issues controlling or even doing anything about this since all the animation/action going on inside the loaded SWF is code-based.
I think you just need to change this line from
var threeSecondFrameCount:int = (stage.frameRate * secondsToSubtract);
to
var threeSecondFrameCount:int = (stage.frameRate / secondsToSubtract);
not sure is this what you want or not.